incubator-heraldry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From quellho...@apache.org
Subject svn commit: r449142 [2/31] - in /incubator/heraldry: idp/ idp/pip/ idp/pip/branches/ idp/pip/tags/ idp/pip/trunk/ idp/pip/trunk/app/ idp/pip/trunk/app/controllers/ idp/pip/trunk/app/helpers/ idp/pip/trunk/app/models/ idp/pip/trunk/app/views/ idp/pip/tr...
Date Sat, 23 Sep 2006 01:37:43 GMT
Added: incubator/heraldry/idp/pip/trunk/app/controllers/application.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/application.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/application.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/application.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,100 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Filters added to this controller will be run for all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+class ApplicationController < ActionController::Base
+  include AuthenticatedSystem
+  include ExceptionNotifiable
+  include SslRequirement
+  include ProprietaryCodeEngine
+
+  before_filter :login_required
+  # Require ssl for all requests except those excluded in individual controllers
+  unless APP_CONFIG[:ssl_disabled]
+    ssl_required
+  end
+
+  protected
+  # Paginate a collection of objects according to the specified options
+  #
+  # ====Parameters
+  # collection:: Array of objects
+  # options:: per_page:: Number of objects to show per page.
+  # page:: Page number of the current page.
+  def paginate_collection(collection, options = {})
+    default_options = {:per_page => 10, :page => 1}
+    options = default_options.merge options
+
+    pages = Paginator.new self, collection.size, options[:per_page], options[:page]
+    first = pages.current.offset
+    last = [first + options[:per_page], collection.size].min
+    slice = collection[first...last]
+    return [pages, slice]
+  end
+  
+  # Returns the account username from the url.
+  # i.e. account_subdomain with http://user.idp.com/ => user
+  # This method is also available as a helper method.
+  def account_subdomain
+    @account_subdomain ||= get_account_subdomain(request.host, AppConfig.host(request.host))
+  end
+  
+  # Returns the account subdomain from the _request_host_.
+  #
+  # ====Paremeters
+  # request_host:: The url being requested. (user.idp.com)
+  # app_host:: The base url for the app. (idp.com)
+  #
+  # ====Example
+  # get_account_subdomain('user.idp.com', 'idp.com') => 'user'
+  def get_account_subdomain(request_host, app_host)
+    if request_host =~ /(.*?)\.?#{app_host}$/ && !($1.empty? || $1 == 'www')
+      $1
+    elsif APP_CONFIG[:restricted_names].include?(request_host.split('.').last)
+      request_host
+    else
+      nil
+    end
+  end
+  
+  # Creates a string representing a users identity url. This method is also
+  # available as a helper method.
+  #
+  # ====Parameters
+  # hsh is a hash of options described below.
+  # username:: User#login.
+  # app_host:: The base domain for the application.
+  #
+  # ====Example
+  # identity_url(:username => 'user', :app_host => 'idp.com') => 'user.idp.com'
+  def identity_url(hsh)
+    if APP_CONFIG[:restricted_names].include?(hsh[:username].split('.').last)
+      hsh[:username]
+    else
+      "#{hsh[:username]}.#{AppConfig.host(request.host)}"
+    end
+  end
+  
+  # Stores a secret code that must be passed when getting the avatar image.
+  # This prevents image spoofing by other sites
+  def create_secret_image_code
+    session[:secret_code] ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{current_user.login}--")
+  end
+  
+  helper_method(:account_subdomain, :identity_url, :create_secret_image_code)
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/avatar_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/avatar_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/avatar_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/avatar_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+#--
+# TODO DOCUMENTATION: Document this controller.
+class AvatarController < ApplicationController
+  # Return the _current_user_'s Avatar.
+  #
+  # Should be called via a view using <img src="avatar/show" />.
+  def show
+    return(render :text => 'No access') unless session[:secret_code] && params[:secret_code] == session[:secret_code]
+
+    @user = User.find(:first, :select => "users.id, avatars.content_type, db_files.data",
+      :conditions => ['users.login = ?', current_user.login],
+      :joins => 'inner join avatars on users.id = avatars.user_id inner join db_files on avatars.db_file_id = db_files.id')
+    if (@user.respond_to?(:data) && @user.data)
+      send_data(@user.data, :type => @user.content_type, :disposition => 'inline')
+    else
+      send_file('public/images/id_image.gif', :type => 'image/gif', :disposition => 'inline')
+    end
+  end
+
+  # Allow the user to upload an avatar image. Redirects to 
+  # AccountController#congratulations.
+  # ====params
+  # avatar_data:: An uploaded picture.
+  def create
+    if params[:user] && params[:user][:avatar_data]
+      if params[:user][:avatar_data].size <= 0
+        flash[:error] = "Please choose an image to upload."
+      elsif !Technoweenie::ActsAsAttachment.content_types.include?(file_type = params[:user][:avatar_data].content_type.strip)
+        flash[:error] = "Sorry, we only support jpg, png, and gif files for ID Images."
+      elsif current_user.update_attributes(params[:user])
+        flash[:notice] = "Your ID Image was uploaded successfully"
+      else
+        flash[:error] = "Your ID Image was not uploaded."
+      end
+    end
+    redirect_to :controller => 'account', :action => 'congratulations'
+  end
+
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/captcha_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/captcha_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/captcha_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/captcha_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,50 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == About
+# CaptchaController is responsible for returning a captcha image
+# to be displayed on user signup.
+#
+# == Requirements
+# Does not require SSL or login.
+class CaptchaController < ApplicationController
+  skip_before_filter :login_required
+  skip_before_filter :ssl_required
+  
+  # Returns a captcha image to display.
+  # The captcha code will be saved in session['captcha_code'].
+  # ====Example
+  # Call this method from your views using <img src="/captcha/new">.
+  def new
+    create_captcha_image
+    prevent_caching
+    return send_file(@captcha.filename, :file_name => 'captcha_image', 
+                     :type => 'image/png', :disposition => 'inline')
+  end
+
+private
+  def create_captcha_image
+    @captcha = IdpCaptcha.new
+    @captcha.generate
+    @session['captcha_code'] = @captcha.code
+  end
+
+  def prevent_caching
+    response.headers['Expires'] = '0'
+    response.headers['Cache-Control'] = 'max-age=0'
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/ledgers_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/ledgers_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/ledgers_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/ledgers_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == About
+# LedgersController is responsible for displaying account activity
+# to the user.
+#
+# == Requirements
+# SSL and login are required on all actions.
+class LedgersController < ApplicationController
+  # Alias for list.
+  def index
+    list
+    render :action => 'list' unless performed?
+  end
+
+  # Show all activity for the _current_user_, most recent first.
+  def list
+    @ledger_pages, @ledgers = paginate :ledgers, :conditions => ['user_id = ?', current_user.id], :order => 'created_at desc', :per_page => 10
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/profiles_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/profiles_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/profiles_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/profiles_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,133 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == About
+# ProfilesController is responsible for displaying trust profiles
+# to the user.
+#
+# == Requirements
+# SSL and login are required on all actions.
+#
+# Destroy, create, and update may only be accessed via a post method.
+class ProfilesController < ApplicationController
+  before_filter :login_required
+  before_filter :find_profile, :only => [:show, :edit, :update, :destroy, :members]
+  before_filter :find_global_or_owned_property_types, :only => [:new, :edit, :create, :update]
+  
+  # Alias for list.
+  def index
+    list
+    render :action => 'list' unless performed?
+  end
+
+  # GET should only be used for operations which are 'safe', or read-only. So require
+  # post for all actions which change state.
+  #  
+  # http://www.w3.org/2001/tag/doc/whenToUseGet.html
+  verify :method=>:post, :only=>[:destroy, :create, :update],
+         :redirect_to=> {:action=>:list}
+
+  # Show all profiles for _current_user_, sorted by the order they were created.
+  # ====params
+  # page:: Number indicating the current page.
+  def list
+    @profile_pages, @profiles = paginate_collection current_user.profiles, {:per_page => 10, :order_by => 'created_at DESC', :page => params[:page]}
+  end
+
+  # Display a form for the creation of a new profile.
+  def new
+    @profile ||= current_user.profiles.new
+    current_user.properties.reload
+  end
+  
+  # Edit an existing profile.
+  # ====params
+  # id:: Profile#id
+  def edit
+    current_user.properties.reload
+  end
+  
+  # Show the Trusts that belong to this Profile
+  # ====params
+  # id:: The Profile#id
+  def members
+    @profile = current_user.profiles.find(params[:id], :include => :trusts)
+  end
+
+  # Create a new profile.  May only be accessed with a post request.
+  # ====params
+  # profile:: Array containing properties for the Profile.
+  # property:: Array of Property#id's to be associated with the Profile.
+  #--
+  # TODO: Do we use ajax saving here?  Can / should it be removed?
+  def create
+    @profile = current_user.profiles.create(params[:profile])
+    @profile.add_properties(params[:property])
+
+    if @profile.save
+      flash[:notice] = 'Profile was successfully created.'
+      redirect_to :action => 'list'
+    else
+      render :action => 'new' 
+    end
+  end
+
+  # Update a profile
+  # ====params
+  # property:: Array of Property#id's to be associated with the Profile.
+  # ====params[:profile]
+  # title:: String for Profile#title
+  # description:: String for Profile#description
+  def update
+    if @profile.update_attributes(params[:profile])
+      @profile.add_properties(params[:property])
+      current_user.ledgers.create(:source => 'You', :event => 'Profile Update',
+                                  :target => '', :source_ip => request.remote_ip, 
+                                  :login => current_user.login, :result => 'Success' )
+      flash[:notice] = 'Profile was successfully updated.'
+      redirect_to :action => 'list'
+    else
+      render :action => 'edit'
+    end
+  end
+
+  # Destroy a profile.
+  # ====params
+  # id:: Profile#id
+  def destroy
+    @profile.destroy
+    respond_to do |type|
+      type.html { redirect_to :action => 'list' }
+      type.js   { render }
+    end
+  end
+
+  protected
+  # TODO Documentation: Comment these two methods?  Is it necessary.
+    def find_profile # :nodoc:
+      @profile = current_user.profiles.find(params[:id])
+    end
+
+    def find_global_or_owned_property_types # :nodoc:
+      @global_or_owned_property_types ||= PropertyType.roots_global_or_owned_by(current_user)
+    end
+
+    def associate_properties_with_profile(properties)
+      @profile.properties.clear
+      @profile.add_properties(properties)
+    end
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/property_types_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/property_types_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/property_types_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/property_types_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,117 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class PropertyTypesController < ApplicationController
+
+  # Display the _current_user_'s master profile.
+  #
+  # The master profile is the set of all properties associated with this user.
+  # #add_category, #add_property, #add_sub_category, #destroy_category,
+  # #destroy_property, #destroy_sub_category, 
+  def index
+    current_user.properties.reload
+    @global_or_owned_property_types = PropertyType.roots_global_or_owned_by(current_user)
+  end
+
+  def create
+    case params[:type]
+    when 'category'
+      create_category_with_subcategory_and_property_type
+      render_action = 'create_category'
+    when 'sub_category'
+      @category       = PropertyType.find(params[:parent])
+      create_subcategory_with_property_type(@category)
+      render_action = 'create_sub_category'
+    when 'property'
+      @sub_category = PropertyType.find(params[:parent])
+      create_property_type(@sub_category)
+      render_action = 'create_property'
+    else
+      raise 'IncorrectPropertyCreation'
+    end
+    respond_to do |wants|
+      wants.html { redirect_to :action => :index }
+      wants.js   { render :action => render_action }
+    end
+  end
+
+  def update
+    update_properties(params[:property])
+    update_property_titles(params[:category_title])
+    update_property_titles(params[:property_title])
+    
+    case params[:type]
+    when 'profile'
+      flash[:notice] = current_user.save ? "Your profile has been updated." : "Your profile could not be updated."
+      redirect_to :action => :index
+    when 'category'
+      @category = PropertyType.find(params[:id])
+      render :action => 'update_category'
+    end
+  end
+
+  def destroy
+    @property_type = PropertyType.find(params[:id])
+    destroy_property_type(@property_type)
+  end
+  
+private
+  def create_category_with_subcategory_and_property_type
+    @category       = PropertyType.root.children.create(:title => 'New Category', 
+                                                        :short_name => 'new_category', 
+                                                        :is_global => false, :user => current_user)
+    create_subcategory_with_property_type(@category)
+  end
+
+  def create_subcategory_with_property_type(category)
+    @sub_category   = category.children.create(:title => 'New Sub-Category', 
+                                               :short_name => 'new_sub_category', 
+                                               :is_global => false, :user => current_user)
+    create_property_type(@sub_category)
+  end
+  
+  def create_property_type(sub_category)
+    @property_type = sub_category.children.create(:title => 'New Property', :short_name => 'new_property', 
+                                                  :is_global => false, :user => current_user)
+    @property = current_user.properties.create(:property_type => @property_type)
+  end
+
+  def destroy_property_type(property_type)
+    if property_type.is_not_global_and_is_owned_by?(current_user)
+      property_type.destroy
+      return true
+    else
+      raise "Property type is not global and/or owned by #{current_user.login}"
+    end
+  end
+
+  def update_properties(properties)
+    properties ||= []
+    properties.each do |key, value|
+      property = current_user.properties.find_by_id(key.to_i)
+      property.update_attribute(:value,value) unless property.nil?
+    end
+  end
+
+  def update_property_titles(property_titles)
+    property_titles ||= []
+    property_titles.each do |key, value|
+      property_title = PropertyType.find_by_id(key.to_i)
+      property_title.update_attribute(:title,value) unless property_title.nil? || !property_title.is_not_global_and_is_owned_by?(current_user)
+    end
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/server_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/server_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/server_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/server_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,628 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+begin
+  require_gem "ruby-openid", ">= 1.0"
+rescue LoadError
+  require "openid"
+end
+
+require 'rexml/document'
+
+# == About
+# ServerController handles all OpenID interchange between consumer sites and the app. 
+# It also manages the xml api for OpenID. See www.openiedenabled.com for more information.
+#
+# == Requirements
+# Login is required on all actions if the request is made from a browser.
+# Requests from consumer sites do not require a login.
+#
+# SSL is only required if the initial request is made via SSL.
+class ServerController < ApplicationController
+  before_filter :validate_post_is_secure, :except => [:index]
+  layout nil
+  skip_before_filter :ssl_required
+  before_filter :check_for_xml, :only => :index
+  before_filter :login_required,  :only => [:trust_request, :decision]
+  before_filter :check_for_human, :only => :index
+  before_filter :verify_current_user_owns_identity_url, :only => :index
+
+  # The primary point of entry for all outside contact with server controller.
+  # Handles three types of requests: one from consumer sites, one from users at a browser,
+  # and a third from the xml api.
+  #
+  # ====Consumer sites
+  # Consumer sites make requests to initiate associations and verify association data.
+  # These requests do not require a login or ssl.
+  #
+  # ====User requests
+  # These requests are redirects from a consumer site that determine if the consumer
+  # site is allowed access to the user's information.
+  #
+  # ====XML requests
+  # These are similar to user requests except make use of the XML api. In addition, there
+  # is additional functionality for creating trusts.
+  def index
+    return render(:text => "This is an OpenID server endpoint.") unless openid_request
+
+    if checkid_request?
+      if consumer_site_is_authorized?
+        log_the_action
+        inform_the_consumer_site :it_is_authorized
+      elsif is_xml_request?
+        inform_the_xml_agent :it_is_not_authorized
+      elsif request_is_checkid_immediate?
+        inform_the_consumer_site :it_is_not_authorized
+      elsif request_is_checkid_setup?
+        redirect_user_to_create_new_authorization
+      else
+        raise 'The chain should not have gotten this far in Server#index'
+      end
+    else # Must be an association request
+      inform_the_consumer_site :it_has_an_association
+    end
+  end
+
+  # Process the User's decision on an openid.checkid_setup request.
+  # ====params
+  # query:: Original openid query string.
+  # trust_profile:: Trust#id of the trust profile being used. Use -1 if a new 
+  #                 trust_profile is being created.
+  # profile_name:: Name of the new Profile (if one is being created).
+  # property:: Array of property ids to use with the Profile (if one is 
+  #            being created).
+  # keep_until:: The length of time to for the Trust to be active. 
+  #              Accepted values: 'forever', 'exact', 'once'.
+  # date:: The exact date at which the Trust expires. A hash of three self 
+  #        explanatory keys: :year => yyyy, :month => mm, & :day => dd.
+  # yes.y:: If this contains a value, then the user approved the trust_request.
+  def decision 
+    return unless trust_request_param_exists? && trust_profile_chosen?
+
+    params.merge! CGIMethods.parse_query_parameters(params[:query])
+    authorize_the_consumer_site unless consumer_site_is_authorized?
+    inform_the_consumer_site(:it_is_authorized) unless performed?
+  end
+
+protected
+  def trust_request_param_exists?
+    unless params[:query]
+      flash[:error] = 'Sorry, this trust request has already expired.'
+      redirect_to(:controller => 'account', :action => 'welcome')
+      return false
+    end
+    true
+  end
+
+  def trust_profile_chosen?
+    unless params[:trust_profile]
+      flash[:error] = 'Please create a trust profile.'
+      redirect_to(:controller => 'profiles', :action => 'new') 
+      return false
+    end
+    true
+  end
+
+  def checkid_request?
+    openid_request.is_a? OpenID::Server::CheckIDRequest
+  end
+
+  def required_fields
+    @required_fields ||= params['openid.sreg.required'] ? params['openid.sreg.required'].split(',') : []
+  end 
+
+  def optional_fields
+    @optional_fields ||= params['openid.sreg.optional'] ? params['openid.sreg.optional'].split(',') : []
+  end
+  
+  # Returns true if the user is logged in and owns the trust_root.
+  # ====Parameters
+  # url:: The User's identity url.
+  # trust_root:: The consumer site's trust root.
+  # required_properties:: An array of properties the Profile must have.
+  #                       ! NOT CURRENTLY USED !
+  #--
+  # TODO: Make consumer_site_is_authorized? return false if the Profile does not have
+  #       the required properties.
+  def consumer_site_is_authorized?
+    return false unless current_user
+    if user_owns_identity_url?
+      return true if (trust = current_user.trusts.find_by_trust_root(openid_request.trust_root)) && trust.active?
+    end
+    return false
+  end
+ 
+  def request_is_checkid_immediate?
+    openid_request.immediate
+  end
+
+  def request_is_checkid_setup?
+    !openid_request.immediate
+  end
+
+  # Returns true if the current user owns openid_request.identity_url
+  def user_owns_identity_url?
+    current_user && current_user.login.downcase == extract_identity(openid_request.identity_url)
+  end
+
+  def log_the_action
+    Ledger.create(:source => openid_request.trust_root, :event => 'Trust Request', :target => openid_request.identity_url,
+                  :source_ip => request.remote_ip, :login => current_user.login, :result => 'Authorized')
+  end
+
+  def inform_the_consumer_site(action)
+    case action
+    when :it_is_authorized
+      @trust ||= current_user.trusts.find_by_trust_root(openid_request.trust_root)
+      @resp = openid_request.answer(true)
+      add_sreg
+    when :it_is_not_authorized
+      retry_query = params.delete_if {|key, val| val.nil?}
+      retry_query['openid.mode'] = 'checkid_setup'
+      setup_url = OpenID::Util.append_args(server_url(:action => 'index'), retry_query)
+	    @resp = openid_request.answer(false, setup_url)
+      # Hackery to circumvent JanRain library bug in req.answer.
+      @resp.fields['user_setup_url'] = setup_url 
+    when :it_has_an_association
+      @resp = server.handle_request(openid_request)
+    else
+      raise "Bad action: #{action}"
+    end
+    render_response
+  end
+
+  def redirect_user_to_create_new_authorization
+    return render_trust_request(request.env['QUERY_STRING'])
+  end
+
+  def a_profile_was_chosen?
+    !(params[:trust_profile] == '-1')
+  end
+
+  def find_the_profile
+    @profile = current_user.profiles.find_by_id(params[:trust_profile])
+  end
+
+  def create_a_new_profile
+    @profile = current_user.profiles.build(:title => params[:profile_name])
+    @profile.add_properties(params[:property])
+    unless @profile.save || ((!params[:profile_name] || params[:profile_name].empty?) &&
+                              params[:keep_until] == 'once')
+      current_user.profiles.reload
+      set_flash_error_message
+      @profile = nil
+    end
+  end
+
+  def set_flash_error_message
+    if @profile.errors.full_messages.include?('Title can\'t be blank')
+      flash.now[:error] = @profile.errors.full_messages.delete_if{|m| m == 'Title can\'t be blank'} <<
+                          'Please choose or create a trust profile.'
+    else
+      flash.now[:error] = @profile.errors.full_messages
+    end
+  end
+
+  def authorize_the_consumer_site
+    if a_profile_was_chosen?
+      find_the_profile
+    else
+      create_a_new_profile
+    end
+    unless @profile
+      flash.now[:error] == 'Invalid Profile' unless flash[:error]
+      return render_trust_request(params[:query])
+    end
+
+    create_trust
+    log_the_action
+  end
+
+  def create_trust
+    case params[:keep_until]
+    when 'forever'  
+      expires_at = nil
+    when 'exact'
+      expires_at = Time.gm(params[:date][:year], params[:date][:month], params[:date][:day]).utc
+    end
+    if @trust = @profile.trusts.find_by_trust_root(openid_request.trust_root)
+      @trust.update_attributes(:profile => @profile, :expires_at => expires_at)
+    else
+      @trust = Trust.create :profile => @profile, :expires_at => expires_at, :trust_root => openid_request.trust_root
+    end
+    @trust.update_attributes(:expires_at => Time.now.utc) if params[:keep_until] == 'once'
+  end
+
+  def openid_request
+    unless @openid_request
+       params.each {|key, val| params[key] = '' if val.nil?}
+       @openid_request = server.decode_request(params.delete_if{|key, val| key == 'openid.session_type' && val == ''})
+    end
+    @openid_request
+  end
+
+  # Returns true if the _current_user_ owns the identity url.
+  # Identity urls follow the format of http://idp.com/user/[_user_login_] and
+  # http://[_user_login_].idp.com/
+  def verify_current_user_owns_identity_url
+    if !openid_request.is_a?(OpenID::Server::CheckIDRequest) || openid_request.mode == 'checkid_immediate' ||
+       user_owns_identity_url?
+      return true
+    else
+      flash[:error] = "You do not own #{CGI.escapeHTML(params['openid.identity'])}." +
+                    " Please login with an account that owns this url."
+      store_location
+      redirect_to :controller => 'account', :action => 'login' and return false
+    end
+  end
+  
+  # If the request is coming from a user at a browser, require the user to login.
+  def check_for_human
+    session[:previous_protocol] = request.protocol
+    login_required if openid_request.is_a?(OpenID::Server::CheckIDRequest) && openid_request.mode == 'checkid_setup'
+  end
+
+  def server # :nodoc:
+    @server ||= OpenID::Server::Server.new(ActiveRecordOpenIDStore.new)
+  end
+  
+  # Gets the username from an identity string
+  # extract_identity('http://user.idp.com') => 'user'
+  # extract_identity('http://idp.com/user/user_login') => 'user_login'
+  #--
+  # TODO: Verify that this isn't the same as a method in ApplicationController
+  def extract_identity(uri)
+    return $1.downcase if uri =~ %r[/user/([a-zA-Z_1-9]*)] || uri =~ %r[://([a-zA-Z_1-9]*)?\.#{AppConfig.host(request.host)}] || uri =~ %r[://(.*?)/?$]
+    return nil
+  end
+  
+  # this method needs to check three things:
+  # 1. Is the user logged in
+  # 2. Is the given URL the identity_url for the logged in user?
+  # 3. Is the trust root approved?
+  # 
+  
+  # Adds the requested profile data to the openid query string.
+  #
+  # ====Parameters
+  # required:: An array of required fields.
+  # optional:: An array of optional fields.
+  # response:: The openid response the fields are being added to.
+  # profile:: The profile data is retrieved from.
+  #--
+  # TODO: Merge required and optional so that only one argument is passed.
+  def add_sreg
+    sreg = {}
+    fields = (required_fields || []) + (optional_fields || [])
+    openid = current_user.properties.openid
+    profile = @trust ? @trust.profile : nil
+    unless profile.nil?
+      fields.each do |field|
+        if property = profile.properties.send("value_for_#{openid[field]}")
+          sreg[field] = format_sreg(property, field)
+        end
+      end
+    end
+    
+    @resp.add_fields('sreg', sreg)  
+  end
+
+  # The conversion parameters for OpenID gender.
+  #--
+  # TODO: Is there a better place to put this.
+  OPENID_SREG_GENDER = {'male' => 'm', 'female' => 'f'}
+
+  # Format a property value to match the format required by OpenID.
+  # ====Parameters
+  # property:: Property#value
+  # sreg:: The lowercase sreg parameter. i.e. - 'dob' or 'gender'
+  def format_sreg(property, sreg)
+    return '' unless property
+    
+    case sreg.downcase
+    when 'dob'
+      return property.to_s
+    when 'gender'
+      return OPENID_SREG_GENDER[property.downcase] || ''
+    # Hacky way to handle american timezones
+    #--
+    # TODO: Make this not so hacky. Maybe use a model to convey idea of timezone.
+    #++
+    # This really isn't something that should exist within ServerController.
+    when 'timezone'
+      case property
+      when 'us_eastern'
+        return 'America/New_York'
+      when 'us_central'
+        return 'America/Chicago'
+      when 'us_mountain'
+        return 'America/Denver'
+      when 'us_pacific'
+        return 'America/Los_Angeles'
+      else
+        return property
+      end
+    else
+      return property
+    end
+  end
+
+  # Renders the trust request page.
+  # ====Parameters
+  # req:: The OpenID::Server::CheckIDRequest object.
+  # required_fields:: An array of required fields.
+  # optional_fields:: An array of optional fields.
+  # query_string:: The original openid query_string.
+  def render_trust_request(query_string)
+    required_fields.map!{ |f| current_user.properties.openid[f] }
+    optional_fields.map!{ |f| current_user.properties.openid[f] }
+    @openid_map = current_user.properties.openid
+    @properties = current_user.properties.delete_if{ |p| !(required_fields + optional_fields).include?(p.property_type.short_name)}
+    @trust_root      = openid_request.trust_root
+    @identity_url    = openid_request.identity_url
+    @query_string    = query_string
+    return render(:action => 'trust_request', :layout => 'application')
+  end
+
+  # Renders the redirect response for an OpenID request.
+  # ====Parameters
+  # response:: An OpenID::Server::OpenIDResponse object.
+  def render_response
+    response.headers['Content-Type'] = 'charset=utf-8'
+    @resp = server.encode_response(@resp)
+    return render_xml_response if is_xml_request?
+    case @resp.code
+    when OpenID::Server::HTTP_OK
+      render :text => @resp.body, :status => 200
+    when OpenID::Server::HTTP_REDIRECT
+      redirect_to @resp.redirect_url
+    else
+      render :text => @resp.body, :status => 400
+    end   
+  end
+
+	 	   
+  # Stops the filter chain if the request is meant for the XML api. 
+  #-- 
+  # TODO: Document xml api. 
+  def check_for_xml 
+    return true unless is_xml_request? 
+    return(render(:text => '<Response>Error: bad xml</Response>')) unless @request.env['RAW_POST_DATA'] && !@request.env['RAW_POST_DATA'].strip.empty? 
+
+    # headers['Content-Type'], NOT headers['CONTENT_TYPE'] 
+    @response.headers['CONTENT_TYPE'] = 'text/xml; charset=utf-8' 
+    @response.headers['Content-Type'] = 'text/xml; charset=utf-8' 
+
+    xml = REXML::Document.new(request.env['RAW_POST_DATA']) 
+    login_user(xml) 
+    return(render(:text => '<Response>bad username or password</Response>') and false) unless current_user 
+
+    begin 
+      (delete_trust(xml) and return false) if is_delete_trust? 
+      (create_trust_xml(xml) and return false) if is_create_trust? 
+      (xml_profile_list(xml) and return false) if is_profile_list? 
+      (xml_query_profile(xml) and return false) if is_query_profile? 
+
+      params.merge!(get_params_from_xml(xml)) 
+
+	 	  create_trust_if_necessary(xml) 
+	 	rescue 
+ 	    return(render(:text => '<Response>Error: bad xml format.</Response>')) 
+    end
+  end
+
+  ########## For handling xml requests ############# 
+	 	   
+  # Returns true if this is an xml request. 
+  def is_xml_request? 
+    request.env['CONTENT_TYPE'] =~ %r[(application|text)/xml] 
+  end 
+	 	   
+  # Returns true if this is an xml request to delete a trust. 
+  def is_delete_trust? 
+    request.env['RAW_POST_DATA'] =~ %r[<DeleteTrust>] 
+  end 
+	 	   
+  # Parses and executes a delete trust command. 
+  # 
+  # ====Parameters 
+  # xml:: The raw xml post data. 
+  #-- 
+  # TODO DOCUMENTATION: Explain the format. 
+  def delete_trust(xml) 
+    if current_user 
+      trust_root = xml.root.get_elements('TrustRoot').first.text 
+      unless trust_root.empty? 
+        @trust = current_user.trusts.find(:first, :conditions => ['trust_root = ?', trust_root]) 
+        if @trust 
+          @trust.destroy 
+          return render(:text => "<Response>success</Response>") 
+        end 
+      end 
+    end 
+    render :text => '<Response>trust root does not exist</Response>' 
+  end 
+   
+  # Returns true if this is an xml request to delete a trust. 
+  def is_create_trust? 
+    request.env['RAW_POST_DATA'] =~ %r[<CreateTrust>] 
+  end 
+   
+  # Parses and executes a create trust command. 
+  # 
+  # ====Parameters 
+  # xml:: The raw xml post data. 
+  #-- 
+  # TODO DOCUMENTATION: Explain the format. 
+  def create_trust_xml(xml) 
+    if current_user 
+      empty = REXML::Element.new('empty') 
+      trust = xml.root.get_elements('Trust').first 
+     
+      return render(:text => "<Response>bad xml</Response>") unless trust 
+      trust_root = (trust.get_elements('TrustRoot').first || empty).text 
+      expires = (trust.get_elements('Expires').first || empty).text 
+      profile_name = (trust.get_elements('AccessProfile').first || empty).text 
+      profile_name = 'public' unless profile_name 
+      @profile = current_user.profiles.find_by_title(profile_name) 
+       
+      return render(:text => "<Response>bad profile</Response>") unless @profile 
+       
+      if ['-1', '0'].include? expires 
+        expires_at = nil 
+      else 
+        expires =~ %r[(\d+)/(\d+)/(\d+)] 
+        expires_at = Time.utc($3.to_i, $2.to_i, $1.to_i) 
+      end 
+       
+      if @trust = Trust.find_by_trust_root(trust_root) 
+        @trust.update_attributes(:profile => @profile, :expires_at => expires_at) 
+      else 
+        @trust = Trust.create(:profile => @profile, :expires_at => expires_at, :trust_root => trust_root) 
+      end 
+      @trust.update_attributes(:expires_at => Time.now.utc) if expires == '0' 
+      return render(:text => '<Response>success</Response>') 
+    end 
+    render :text => '<Response>could not create trust</Response>' 
+  end 
+   
+  # Returns true if this is an xml request to show a list of available profiles. 
+  def is_profile_list? 
+    request.env['RAW_POST_DATA'] =~ %r[<QueryProfileList>] 
+  end 
+   
+  # Parses and executes an xml list profile command. 
+  # ====Parameters 
+  # xml:: The raw xml post data. 
+  #-- 
+  # TODO DOCUMENTATION: Explain the format. 
+  def xml_profile_list(xml) 
+    if current_user 
+      profiles = current_user.profiles.map{|p| p.title}.join(',') 
+      return render(:text => "<Response>#{profiles}</Response>") 
+    end 
+    render :text => '<Response>Internal Error</Response>' 
+  end 
+	 	   
+  # Returns true if this is an xml request to query a profile. 
+  def is_query_profile? 
+    request.env['RAW_POST_DATA'] =~ %r[<QueryProfile>] 
+  end 
+	 	   
+  # Parses and executes an xml query profile command. 
+  # ====Parameters 
+  # xml:: The raw xml post data. 
+  #-- 
+  # TODO DOCUMENTATION: Explain the format. 
+  def xml_query_profile(xml) 
+    if current_user 
+      profile_name = (xml.root.get_elements('AccessProfile').first || empty).text 
+      profile_name = 'public' unless profile_name 
+      @profile = current_user.profiles.find_by_title(profile_name) 
+      return render(:text => "<Response>bad profile</Response>") unless @profile 
+       
+      properties = @profile.properties.map{|p| p.property_type.title }.join(',') 
+      return render(:text => "<Response>#{properties}</Response>") 
+    end 
+    render(:text => "<Response>Internal Error</Response>") 
+  end 
+   
+  # Login the user via an xml request 
+  # ====Parameters 
+  # xml:: The raw xml post data 
+  def login_user(xml) 
+    login = xml.root.get_elements('User').first.text 
+    password = xml.root.get_elements('Password').first.text 
+    self.current_user = User.authenticate(login, password) 
+  end 
+   
+  # Creates a one use trust if necessary for the given trust_root. 
+  #  
+  # ===Parameters 
+  # xml:: The raw xml post data 
+  def create_trust_if_necessary(xml) 
+    profile_name = xml.root.get_elements('Request').first.get_elements('AccessProfile').first.text 
+    profile_name = 'public' unless profile_name 
+    profile = current_user.profiles.find_by_title(profile_name) 
+    return unless profile 
+    hsh = {:profile => profile} 
+    params.merge!(get_params_from_xml(xml)) unless params['openid.mode'] 
+    if @trust = Trust.find_by_trust_root(params['openid.trust_root']) 
+      unless @trust.active? 
+        hsh.merge!(:expires_at => nil)  
+        just_once = true 
+      end 
+      @trust.update_attributes(hsh) 
+    else 
+      @trust = Trust.create :profile => profile, :expires_at => nil, :trust_root => params['openid.trust_root'] 
+      just_once = true 
+    end 
+    @trust.instance_eval "def xml_expire?; #{just_once}; end" 
+  end 
+   
+  # Extracts OpenID params from an xml request and returns them as a hash. 
+  # ====Parameters 
+  # xml:: Raw xml post data. 
+  def get_params_from_xml(xml) 
+    empty = REXML::Element.new('empty') 
+    empty_attr = REXML::Attribute.new('empty') 
+    ret = {} 
+    root = xml.root 
+ 
+    ret.merge!('openid.mode' => "checkid_#{$1.downcase}") if root.xpath =~ /OpenIDCheckID(.*)/ 
+    if req = root.get_elements('Request').first 
+      ret.merge!('openid.identity' => ((req.get_elements('Identity').first || empty).text || '').strip, 
+                 'openid.assoc_handle' => ((req.get_elements('AssocHandle').first || empty).text || '').strip, 
+                 'openid.return_to' => ((req.get_elements('ReturnTo').first || empty).text  || '').strip, 
+                 'openid.trust_root' => ((req.get_elements('TrustRoot').first || empty).text || '').strip) 
+      if sreg = req.get_elements('Sreg').first 
+        ret.merge!('openid.sreg.required' => ((sreg.attribute('required') || empty_attr).value || '').strip, 
+                   'openid.sreg.optional' => ((sreg.attribute('optional') || empty_attr).value || '').strip, 
+                   'openid.sreg.policy_url' => ((sreg.attribute('policy_url') || empty_attr).value || '').strip) 
+      end 
+    end 
+    return ret 
+  end 
+   
+  # Render a response to an xml request. 
+  # Response is rendered in xml. 
+  # ====Parameters 
+  # resp:: An OpenID::Response object. 
+  def render_xml_response 
+    @trust.update_attributes(:expires_at => Time.now.utc) if @trust && @trust.xml_expire? 
+    response.headers['CONTENT_TYPE'] = 'text/xml; charset=utf-8' 
+    response.headers['Content-Type'] = 'text/xml; charset=utf-8' 
+    render :text => "<Response>#{@resp.headers['location'].gsub(/&/,'&#38;')}</Response>" 
+  end
+
+  def inform_the_xml_agent(action)
+    case action
+    when :it_is_not_authorized
+      if request_is_checkid_immediate?
+        setup_url = server_url(:action => 'index')
+        @resp = openid_request.answer(false, setup_url)
+      else
+        @resp = openid_request.answer(false)
+      end
+    else
+      raise "Bad action: #{action}"
+    end
+    render_response
+  end
+
+  helper_method(:openid_request, :required_fields, :optional_fields)
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/site_ping_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/site_ping_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/site_ping_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/site_ping_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Used by monitoring services to determine if the site is running.
+class SitePingController < ApplicationController
+  before_filter :login_required, :except => :index
+  skip_before_filter :ssl_required
+  
+  # Return 'success' if the site is running.
+  def index
+    render_text "success"
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/static_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/static_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/static_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/static_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Uses page caching to display static pages with minimum overhead.
+# Does not require login.
+# Prohibits SSL.
+class StaticController < ApplicationController
+  skip_before_filter :login_required
+  skip_before_filter :ssl_required
+  ssl_prohibited
+  
+  caches_page :terms, :about, :privacy, :resources, :faq
+end

Added: incubator/heraldry/idp/pip/trunk/app/controllers/trusts_controller.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/controllers/trusts_controller.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/controllers/trusts_controller.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/controllers/trusts_controller.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,44 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# For management of Trusts that a user has.
+class TrustsController < ApplicationController
+  # List the existing trusts for _current_user_.
+  # ====params
+  # order_by:: Specifies which column to sort by.  Allowed values are 'trusts.title', 
+  #              'trusts.trust_root', 'profiles.title', and 'trusts.expires_at'
+  # order:: Specifies sort order (A-Z or Z-A).  Allowed values are 'asc' and 'desc'
+  # page:: Number specifing the current page number.
+  def list
+    allow_sort_params = ['trusts.title', 'trusts.trust_root', 'profiles.title', 'trusts.expires_at']
+    @order_by = params[:order_by] && allow_sort_params.include?(params[:order_by].downcase) ? params[:order_by] : 'trusts.created_at'
+    @order = params[:order] && ['asc', 'desc'].include?(params[:order].downcase) ? params[:order] : 'DESC'
+    @trust_pages, @trusts = paginate_collection current_user.trusts.find(:all, :include => :profile, :order => @order_by + ' ' + @order), {:per_page => 10, :page => params[:page]}
+  end
+  
+  # Destroy the given Trust.
+  # ====params
+  # id:: Profile#id
+  def destroy
+    @trust = current_user.trusts.find(params[:id])
+    @trust.destroy       
+    respond_to do |type|
+      type.html { redirect_to :action => 'list' }
+      type.js   { render }
+    end
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/account_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/account_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/account_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/account_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Helper methods for AccountController views
+module AccountHelper
+  # Retrieves the User's login from the identity url in the openid headers if possible.
+  # Returns nil if the identity url is not properly formatted or there is no idenity url.
+  def default_value_for_login
+    if login = get_login_from_query_string
+      return (user = User.find_by_login(login)) ? user.login : login
+    else
+      return nil
+    end
+  end
+  
+  def yadis_header_content
+    login = account_subdomain.gsub(/\./, '_')
+    content_for 'header' do
+      <<-EOS
+        <link rel="openid.server" href="http://#{host_with_port}/server" />
+        <meta http-equiv="X-XRDS-Location" content="http://#{host_with_port }/user/#{login}/yadis" />
+        <meta http-equiv="X-YADIS-Location" content="http://#{host_with_port }/user/#{login}/yadis" />
+      EOS
+    end
+  end
+
+  def using_subdomain?
+    account_subdomain && account_subdomain != 'www'
+  end
+private
+  def get_login_from_query_string
+    if @return_to_query && CGI::unescape(@return_to_query) =~ /openid.\identity=(.*?)&/
+      get_login_from_url($1)
+    else
+      return nil
+    end
+  end
+
+  def get_login_from_url(url)
+    if (url =~ %r[http://((\w+\.){0,2}\w+)\.#{host_with_port}]) || (url =~ %r[/user/((\w+\.){0,2}\w+)]) 
+      $1.gsub(/_/, '.')
+    elsif (login = get_login_from_domain(url))
+      login
+    else
+      nil
+    end
+  end
+
+  def get_login_from_domain(url)
+    url =~ %r[http://((\w+\.){0,2}\w+)]
+    login = $1
+    if url && APP_CONFIG[:restricted_names].include?(login.split('.').last)
+      login
+    else
+      nil
+    end
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/application_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/application_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/application_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/application_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,135 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+  include PropertyDisplayMixin
+
+  # Merges two arrays into a hash.
+  # ====Parameters
+  # keys:: An array of keys for the hash.
+  # values:: An array of values for the hash.
+  def arrays_to_hash(keys,values)
+    hash = {}
+    keys.size.times { |i| hash[ keys[i] ] = values[i] }
+    hash
+  end
+
+  # Returns a string containing the controller name + '/' + controller.action_name
+  def controller_action
+    @controller_action ||= [controller.controller_name, controller.action_name].join('/')
+  end
+
+  # Returns an image link containing the image in images/buttons/help.gif
+  def render_help(title, id=nil, options = {})
+    link_to(image_tag('buttons/help.gif', :size => '22x22'), '#', {:class => "tooltip question-mark", :title => title, :id => "icon-#{id}"}.merge(options))
+  end
+
+  # returns 'selected' for the navigation menu if the controller/action_name matches
+  #
+  #   selected?(/^account/) # matches account/
+  def selected?(pattern)
+    'selected' if controller_action =~ pattern
+  end
+
+  # Returns a div containing the error messages for _object_name_.
+  # ====Parameters
+  # object_name:: A string that is the name of the object we're reporting errors for.
+  # options:: A hash containing options for the messages.
+  #   header_tag:: A valid html header tag (h1, h2, h3, ...)
+  #   id::         An id for the unordered list element.
+  #   class::      A class for the unordered list element.
+  def error_messages_for(object_name, options = {})
+    options = options.symbolize_keys
+    object = instance_variable_get("@#{object_name}")
+    if object && !object.errors.empty?
+      content = content_tag("div",
+        content_tag(
+          options[:header_tag] || "h2",
+          "#{pluralize(object.errors.count, "error")} prohibited this #{object_name.to_s.gsub("_", " ")} from being saved"
+        ) +
+        content_tag("p", "There were problems with the following fields:") +
+        content_tag("ul", object.errors.full_messages.collect { |msg| content_tag("li", msg) }),
+        "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
+      )
+      render :partial => "layouts/errors", :locals => {:content => content}
+    else
+      ""
+    end
+  end
+
+  # Renders an image tag for the current User's Avatar.
+  def current_avatar
+    logged_in? ? 
+      image_tag("/avatar/show?secret_code=#{session[:secret_code]}&", :alt => current_user.login) :  # The '&' is a hack to prevent the appended .png from spoiling the call
+      image_tag('id_image.gif', :alt => "ID Image", :size => '70x70')
+  end
+  
+  # Renders a link to _action_ to sort an object by _title_ in the order specified by _sort_method_.
+  # ====Parameters
+  # title:: The title for the link *and* the property to sort by.
+  # sort_method::'asc' or 'desc'.  Specifies the sort order.
+  # action:: Defaults to :list.  Override to specify a different action to link to.
+  def sort_link_for(title, sort_method, action=:list)
+    link_to title, {:action => action, :order_by => sort_method, :order => (@order_by == sort_method) ? 'desc' : 'asc'},
+                   {:class => 'tooltip', :title => "Sort By #{title}", :id => "header-#{title.downcase.gsub(' ', '-')}"}
+  end
+
+  def row_class(counter)
+    counter % 2 == 0 ? :even : :odd
+  end
+
+  def show_flash?(flash)
+    f = flash.select { |key, val| show_flash_key?(key) }
+    f.empty?
+  end
+
+  def show_flash_key?(key)
+    [:error, :notice].include?(key)
+  end
+
+  def render_children(parent)
+    rendered_children = ""
+    parent.children.each_with_index do |leaf,index| 
+      if leaf.is_global_or_owned_by?(current_user) && leaf.has_children?
+        rendered_children << render(:partial => "sub_category", :object => leaf)
+      elsif current_user.properties.has_property?(leaf)
+        rendered_children << render(:partial => "property", :object => current_user.properties.find_by_property_type(leaf), 
+                                    :locals => { :render_newfield => ( index.zero? && !parent.is_not_global_and_is_owned_by?(current_user) ), :parent => parent} )
+      end 
+    end
+    return rendered_children
+  end
+  
+  ###### METHODS FOR layouts/_header.rhtml ############################  
+  def render_specific_header_items
+    if !on_cached_page? && has_access?(current_user) 
+      render(:partial => '/layouts/logged_in_header_items', :locals => {:current_user => current_user})
+    else
+      (on_login_page? || on_cached_page? ? '' : render(:partial => '/layouts/login_button')) + 
+      render(:partial => '/layouts/regular_header_items')
+    end 
+  end
+  
+  def on_cached_page?
+    controller_action =~ /^static/
+  end
+  
+  def on_login_page?
+    controller_action =~ /^account\/login/
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/ledgers_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/ledgers_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/ledgers_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/ledgers_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module LedgersHelper # :nodoc:
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/profiles_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/profiles_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/profiles_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/profiles_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module ProfilesHelper # :nodoc:
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/property_types_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/property_types_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/property_types_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/property_types_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,86 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module PropertyTypesHelper
+  # If the property_type is owned by the user, allow the user to edit the name.
+  # Otherwise, return an uneditable label.
+  def label_or_input_for(property_type)
+    if property_type.is_not_global_and_is_owned_by?(current_user) 
+      text_field_tag "property_title[#{property_type.id}]", property_type.title, :class => 'profile-title', :id => "property_title_#{property_type.id}"
+    else 
+      "<label for=\"property_type_#{property_type.to_dom_id}\" class=\"profile-title\">#{property_type.title}</label>"
+    end 
+  end
+
+  def sub_category_label_or_input_for(property_type)
+    if property_type.is_not_global_and_is_owned_by?(current_user)
+      text_field_tag "category_title[#{property_type.id}]", property_type.title, :class => 'category-title', :id => "category_title#{property_type.id}"
+    else
+      "<h4 id=\"title_#{property_type.to_dom_id}\" class=\"profile\">#{property_type.title}</h4>"
+    end
+  end
+
+  def category_label_or_input_for(property_type)
+    if property_type.is_not_global_and_is_owned_by?(current_user) 
+      text_field_tag( "category_title[#{property_type.id}]", property_type.title, :id => "category_title_#{property_type.to_dom_id}",
+                                                                                  :class => "category-title",
+                                                                                  :style => "float: left;" ) +
+        "\n<script type=\"text/javascript\">\n" +
+        "Event.observe('category_title_#{property_type.to_dom_id}', 'click', function(event){ CategoryForm.activate_section('#{property_type.to_dom_id}'); });\n" +
+        "</script>"
+    else 
+      '<h2 class="category" style="float: left;">' + 
+        link_to_function( property_type.title, %(CategoryForm.toggle_collapse('#{property_type.to_dom_id}')) ) +
+        '</h2>'
+    end 
+  end
+
+  # Show the delete icon if necessary.  Otherwise, make an empty delete-icon div.
+  def delete_icon_if_necessary(property_type, confirm_message)
+    if property_type.is_not_global_and_is_owned_by?(current_user)
+        link_to_remote( image_tag('buttons/collapse_sm.gif', :size => '16x16', :alt => 'Remove', 
+                                                             :id => "delete_icon_#{property_type.to_dom_id}",
+                                                             :class => 'delete-icon edit-element', 
+                                                             :style => 'margin-top: -3px; display:none'),
+                        :url => { :action => 'destroy', :id => property_type.id },
+                        :confirm => confirm_message)  
+    end 
+  end
+
+  def property_delete_icon_if_necessary(property_type)
+    delete_icon_if_necessary(property_type, 'Are you sure you want to permanently delete this property?') || "<div class='delete-icon'>&nbsp;</div>" 
+  end
+
+  def sub_category_delete_icon_if_necessary(property_type)
+    delete_icon_if_necessary(property_type, 'Are you sure you want to permanently delete this sub_category and all its properties?')
+  end
+
+  def category_delete_icon_if_necessary(property_type)
+    delete_icon_if_necessary(property_type, 'Are you sure you want to permanently delete this category and all its properties?')
+  end
+  
+  def new_subcategory_button(parent)
+    link_to_remote( image_tag('buttons/add_subcategory.gif', :size => '105x21', :alt => 'Create new sub category', :class => 'add-sub-category'), 
+                    :url => { :action => :create, :type => 'sub_category', :parent => parent } )
+  end
+
+  def new_field_button(parent)
+    link_to_remote( image_tag('buttons/add_new_field.gif', :size => '107x22', :alt => 'Add a new field', :class => 'add-field', :style => 'margin-top: -2px;'), 
+                    :url => { :action => :create, :type => 'property', :parent => parent } )
+  end
+
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/server_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/server_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/server_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/server_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,51 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Methods added to this module are available to ServerController views.
+module ServerHelper
+  
+  # Creates a group of hidden input fields that are used by javascript
+  # to properly highlight fields that are included in TrustProfiles.
+  def hidden_fields_for_highlighting
+    current_user.profiles.map do |p|
+      "<input type=\"hidden\" id=\"profile_#{p.id}_properties\"" +
+      " value=\"#{p.properties.map{|prop| prop.id}.join(',')}\" />"
+    end.join("\n")
+  end
+  
+  # Displays text informing the user that a consumer site requests specific properties
+  # if _properties_ is not nil or an empty Array. Otherwise, it informs the user that 
+  # no profile information is requested.
+  #
+  # All output is enclosed in <p> tags.
+  #
+  # properties:: An array of Properties or nil.
+  def text_for_user_notification(properties)
+    unless properties && properties.empty?
+      <<-EOS
+    <p><b><span class="colored">To complete the registration process the site is requesting additional information. Please select a trust profile you would like to associate the site with or create a new one. The Trust Profile you select will determine the information that is shared.</span></b></p>
+    <p style="font-style: italic;">Fields marked with an asterisk (*) are required for successful registration with this site.</p>
+      EOS
+    else
+      <<-EOS
+      <p><b><span class="colored">Please select a Trust Profile you would like
+      to associate the site with or create a new one.  This site is not requesting
+      any additonal profile information from you.</span></b></p>
+      EOS
+    end
+  end
+end
\ No newline at end of file

Added: incubator/heraldry/idp/pip/trunk/app/helpers/site_ping_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/site_ping_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/site_ping_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/site_ping_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module SitePingHelper # :nodoc:
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/static_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/static_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/static_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/static_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module StaticHelper # :nodoc:
+end

Added: incubator/heraldry/idp/pip/trunk/app/helpers/trusts_helper.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/helpers/trusts_helper.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/helpers/trusts_helper.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/helpers/trusts_helper.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Methods in this module can be used by TrustController views.
+module TrustsHelper
+
+  # Properly format the time until _trust_ expires.
+  # ====Parameters
+  # trust:: A Trust object.
+  def format_expired_for(trust)
+    return 'expired' unless trust.active?
+    return 'never' if trust.never_expires?
+    time_ago_in_words(trust.expires_at)
+  end
+
+  def profile_link_for(trust)
+    if trust.profile
+      link_to(trust.profile.title, :controller => 'profiles', :action => 'members', :id => trust.profile)
+    else
+      'Temporary'
+    end
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/association.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/association.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/association.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/association.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,44 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == Schema Information
+# Schema version: 27
+#
+# Table name: associations
+#
+#  id         :integer(11)   not null, primary key
+#  server_url :binary        
+#  handle     :string(255)   
+#  secret     :binary        
+#  issued     :integer(11)   
+#  lifetime   :integer(11)   
+#  assoc_type :string(255)   
+#
+
+begin
+  require_gem "ruby-openid", ">= 1.0"
+rescue LoadError
+  require "openid"
+end
+
+# Stores OpenID Associations. Used in conjunction with the JanRain OpenID libraries.
+class Association < ActiveRecord::Base
+  # Return an OpenID::Association given an Association.
+  def from_record
+    OpenID::Association.new(handle, secret, issued, lifetime, assoc_type)
+  end
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/avatar.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/avatar.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/avatar.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/avatar.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,39 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == Schema Information
+# Schema version: 27
+#
+# Table name: avatars
+#
+#  id           :integer(11)   not null, primary key
+#  user_id      :integer(11)   
+#  filename     :string(255)   
+#  content_type :string(255)   
+#  size         :integer(11)   
+#  width        :integer(11)   
+#  height       :integer(11)   
+#  db_file_id   :integer(11)   
+#  parent_id    :integer(11)   
+#
+
+# This class is used to store user images.
+class Avatar < ActiveRecord::Base
+  acts_as_attachment :content_type => :image, :resize_to => "70x70"
+  belongs_to :user
+
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/ledger.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/ledger.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/ledger.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/ledger.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == Schema Information
+# Schema version: 27
+#
+# Table name: ledgers
+#
+#  id          :integer(11)   not null, primary key
+#  transaction :text          
+#  created_at  :datetime      
+#  source      :string(255)   
+#  event       :string(255)   
+#  target      :string(255)   
+#  login       :string(255)   
+#  result      :string(255)   
+#  source_ip   :string(255)   
+#  user_id     :integer(11)   
+#
+
+# Used to store activity data for a user.
+# Belongs to a User.
+class Ledger < ActiveRecord::Base
+  belongs_to :user
+  
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/nonce.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/nonce.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/nonce.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/nonce.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == Schema Information
+# Schema version: 27
+#
+# Table name: nonces
+#
+#  id      :integer(11)   not null, primary key
+#  nonce   :string(255)   
+#  created :integer(11)   
+#
+
+# Stores nonces for OpenID Associations.
+class Nonce < ActiveRecord::Base
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/open_id_mapping.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/open_id_mapping.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/open_id_mapping.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/open_id_mapping.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,3 @@
+class OpenIdMapping < ActiveRecord::Base
+  has_one :property_type
+end

Added: incubator/heraldry/idp/pip/trunk/app/models/profile.rb
URL: http://svn.apache.org/viewvc/incubator/heraldry/idp/pip/trunk/app/models/profile.rb?view=auto&rev=449142
==============================================================================
--- incubator/heraldry/idp/pip/trunk/app/models/profile.rb (added)
+++ incubator/heraldry/idp/pip/trunk/app/models/profile.rb Fri Sep 22 18:37:26 2006
@@ -0,0 +1,81 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# == Schema Information
+# Schema version: 27
+#
+# Table name: profiles
+#
+#  id          :integer(11)   not null, primary key
+#  user_id     :integer(11)   
+#  title       :string(255)   
+#  description :text          
+#  created_at  :datetime      
+#  updated_at  :datetime      
+#
+
+# Stores a profile for a given user.
+# Profiles are subsets of a user's information that allow for easy
+# association of that data with a specific site.
+class Profile < ActiveRecord::Base
+  attr_protected :user_id, :created_at, :updated_at
+  
+  belongs_to :user
+  has_many :trusts
+  has_and_belongs_to_many :properties do
+    # Defined for profile.properties
+    # Find a property by its property type.
+    # ====Parameters
+    # property_type:: Object of class PropertyType
+    def find_by_property_type(property_type)
+      self.to_a.detect { |p| p.property_type_id == property_type.id }
+    end
+    
+    # Defined for profile.properties
+    # Use value_for_[short_name] to find the value of a property given its PropertyType short_name.
+    # For example: profile.properties.value_for_nickname would return the value for the property that
+    # has a PropertyType with a shortname of nickname.
+    # *args:: String that matches a PropertyType.short_name
+    def method_missing(sym, *args)
+      return super unless sym.to_s =~ /value_for_(\w*)/
+      return nil unless property_type = PropertyType.find_by_short_name($1)
+      (prop = self.find_by_property_type(property_type)) ? (prop.value || '') : nil
+    end
+  end
+  
+  validates_presence_of :user_id, :title
+  validates_uniqueness_of :title, :scope => :user_id
+
+  # Returns true if the profile has all the properties of the property types listed in props.
+  # ====Parameters
+  # *props:: Array of strings that match a PropertyType.short_name
+  def has_properties?(*props)
+    fields = self.properties.map{|p| p.property_type.short_name}
+    fields.superset?(props.flatten)
+  end
+  
+  # Add properties to the profile.
+  # ====Parameters
+  # properties:: Array of Property ids.
+  def add_properties(properties)
+    self.properties.clear
+    return nil unless properties
+    properties.each do |key|
+      self.properties << Property.find(key.to_i)
+    end
+  end
+end



Mime
View raw message