mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-04 06:51:48 +01:00
My apologies for this large, multi-pronged commit. What's here:
* Introduce Tracks::Config class to wrap environment.rb config settings * Remove unused admin and index actions from user_controller * Introduce flash partial and standardize on symbol keys for the flash hash * Replace usages of render_partial with render :partial Two new authentication options! These probably need documentation... * Introduce LDAP authentication option (see configuration in environment.rb.tmpl). Thanks to Jeremy Evans for creating the SimpleLdapAuthenticator plugin. Note: the ldap auth integration test is likely to be fragile. Works for me on OS X with openldap, but your mileage may vary. * Introduce Open ID authentication option (see configuration in environment.rb.tmpl and http://openid.net for more info). Thanks to East Media for the Open ID Consumer Plugin. In environment.rb, you can enable any combination of the three auth options. If you have more than one selected, users can opt between them via their preferences pages. To play with the Open ID auth, you can get an identity at pip.verisignlabs.com. Note that there are some new migrations to support the new authentication options, so don't forget to rake migrate! git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@334 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
4e0b459524
commit
99b734a52c
69 changed files with 1649 additions and 218 deletions
|
|
@ -86,10 +86,10 @@ class ContextController < ApplicationController
|
|||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["notice"] = 'Added new next action.'
|
||||
flash[:notice] = 'Added new next action.'
|
||||
redirect_to :controller => 'todo', :action => 'list'
|
||||
else
|
||||
flash["warning"] = 'The next action was not added. Please try again.'
|
||||
flash[:warning] = 'The next action was not added. Please try again.'
|
||||
redirect_to :controller => 'todo', :action => 'list'
|
||||
end
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ class ContextController < ApplicationController
|
|||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
flash[:warning] = 'An error occurred on the server.'
|
||||
redirect_to :controller => 'todo', :action => 'list'
|
||||
end
|
||||
end
|
||||
|
|
@ -118,9 +118,9 @@ class ContextController < ApplicationController
|
|||
return if request.xhr?
|
||||
|
||||
if @saved
|
||||
flash['notice'] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
else
|
||||
flash['notice'] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
end
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
|
|
@ -133,9 +133,9 @@ class ContextController < ApplicationController
|
|||
@context.attributes = params["context"]
|
||||
@context.name = deurlize(@context.name)
|
||||
if @context.save
|
||||
render_partial 'context_listing', @context
|
||||
render :partial => 'context_listing', :object => @context
|
||||
else
|
||||
flash["warning"] = "Couldn't update new context"
|
||||
flash[:warning] = "Couldn't update new context"
|
||||
render :text => ""
|
||||
end
|
||||
end
|
||||
|
|
@ -148,7 +148,7 @@ class ContextController < ApplicationController
|
|||
if @context.destroy
|
||||
render_text ""
|
||||
else
|
||||
flash["warning"] = "Couldn't delete context \"#{@context.name}\""
|
||||
flash[:warning] = "Couldn't delete context \"#{@context.name}\""
|
||||
redirect_to( :controller => "context", :action => "list" )
|
||||
end
|
||||
end
|
||||
|
|
@ -178,7 +178,7 @@ class ContextController < ApplicationController
|
|||
return @context
|
||||
else
|
||||
@context = nil # Should be nil anyway.
|
||||
flash["warning"] = "Item and session user mis-match: #{@context.user_id} and #{@user.id}!"
|
||||
flash[:warning] = "Item and session user mis-match: #{@context.user_id} and #{@user.id}!"
|
||||
render_text ""
|
||||
end
|
||||
end
|
||||
|
|
@ -189,7 +189,7 @@ class ContextController < ApplicationController
|
|||
return @context
|
||||
else
|
||||
@context = nil
|
||||
flash["warning"] = "Project and session user mis-match: #{@context.user_id} and #{@user.id}!"
|
||||
flash[:warning] = "Project and session user mis-match: #{@context.user_id} and #{@user.id}!"
|
||||
render_text ""
|
||||
end
|
||||
end
|
||||
|
|
@ -199,7 +199,7 @@ class ContextController < ApplicationController
|
|||
if @user == item.user
|
||||
return item
|
||||
else
|
||||
flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!"
|
||||
flash[:warning] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!"
|
||||
render_text ""
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ class LoginController < ApplicationController
|
|||
model :user, :preference
|
||||
layout 'login'
|
||||
skip_before_filter :set_session_expiration
|
||||
|
||||
open_id_consumer if Tracks::Config.auth_schemes.include?('open_id')
|
||||
|
||||
def login
|
||||
@page_title = "TRACKS::Login"
|
||||
case request.method
|
||||
|
|
@ -13,15 +14,68 @@ class LoginController < ApplicationController
|
|||
# of inactivity
|
||||
session['noexpiry'] = params['user_noexpiry']
|
||||
msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
|
||||
flash['notice'] = "Login successful: session #{msg}"
|
||||
flash[:notice] = "Login successful: session #{msg}"
|
||||
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year }
|
||||
redirect_back_or_default :controller => "todo", :action => "index"
|
||||
else
|
||||
@login = params['user_login']
|
||||
flash['warning'] = "Login unsuccessful"
|
||||
flash[:warning] = "Login unsuccessful"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def begin
|
||||
# If the URL was unusable (either because of network conditions,
|
||||
# a server error, or that the response returned was not an OpenID
|
||||
# identity page), the library will return HTTP_FAILURE or PARSE_ERROR.
|
||||
# Let the user know that the URL is unusable.
|
||||
case open_id_response.status
|
||||
when OpenID::SUCCESS
|
||||
# The URL was a valid identity URL. Now we just need to send a redirect
|
||||
# to the server using the redirect_url the library created for us.
|
||||
|
||||
# redirect to the server
|
||||
redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), url_for(:action => 'complete'))
|
||||
else
|
||||
flash[:warning] = "Unable to find openid server for <q>#{params[:openid_url]}</q>"
|
||||
redirect_to :action => 'login'
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
case open_id_response.status
|
||||
when OpenID::FAILURE
|
||||
# In the case of failure, if info is non-nil, it is the
|
||||
# URL that we were verifying. We include it in the error
|
||||
# message to help the user figure out what happened.
|
||||
if open_id_response.identity_url
|
||||
flash[:message] = "Verification of #{open_id_response.identity_url} failed. "
|
||||
else
|
||||
flash[:message] = "Verification failed. "
|
||||
end
|
||||
flash[:message] += open_id_response.msg.to_s
|
||||
|
||||
when OpenID::SUCCESS
|
||||
# Success means that the transaction completed without
|
||||
# error. If info is nil, it means that the user cancelled
|
||||
# the verification.
|
||||
@user = User.find_by_open_id_url(open_id_response.identity_url)
|
||||
unless (@user.nil?)
|
||||
flash[:message] = "You have successfully verified #{open_id_response.identity_url} as your identity."
|
||||
session['user_id'] = @user.id
|
||||
redirect_back_or_default :controller => 'todo', :action => 'index'
|
||||
else
|
||||
flash[:warning] = "You have successfully verified #{open_id_response.identity_url} as your identity, but you do not have a Tracks account. Please ask your administrator to sign you up."
|
||||
end
|
||||
|
||||
when OpenID::CANCEL
|
||||
flash[:message] = "Verification cancelled."
|
||||
|
||||
else
|
||||
flash[:warning] = "Unknown response status: #{open_id_response.status}"
|
||||
end
|
||||
redirect_to :action => 'login' unless performed?
|
||||
end
|
||||
|
||||
def signup
|
||||
if User.find_all.empty? # the first user of the system
|
||||
|
|
@ -53,7 +107,7 @@ class LoginController < ApplicationController
|
|||
@user = User.authenticate(user.login, params['user']['password'])
|
||||
@user.create_preference
|
||||
@user.save
|
||||
flash['notice'] = "Signup successful for user #{@user.login}."
|
||||
flash[:notice] = "Signup successful for user #{@user.login}."
|
||||
redirect_back_or_default :controller => "todo", :action => "index"
|
||||
end
|
||||
end
|
||||
|
|
@ -70,8 +124,8 @@ class LoginController < ApplicationController
|
|||
def logout
|
||||
session['user_id'] = nil
|
||||
reset_session
|
||||
flash['notice'] = "You have been logged out of Tracks."
|
||||
redirect_to :controller => "login", :action => "login"
|
||||
flash[:notice] = "You have been logged out of Tracks."
|
||||
redirect_to :action => "login"
|
||||
end
|
||||
|
||||
def check_expiry
|
||||
|
|
|
|||
|
|
@ -26,19 +26,19 @@ class NoteController < ApplicationController
|
|||
note.attributes = params["new_note"]
|
||||
|
||||
if note.save
|
||||
render_partial 'notes_summary', note
|
||||
render :partial => 'notes_summary', :object => note
|
||||
else
|
||||
render_text ""
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
note = check_user_return_note
|
||||
if note.destroy
|
||||
render_text ""
|
||||
render :text => ''
|
||||
else
|
||||
flash["warning"] = "Couldn't delete note \"#{note.id.to_s}\""
|
||||
render_text ""
|
||||
flash[:warning] = "Couldn't delete note \"#{note.id.to_s}\""
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -46,10 +46,10 @@ class NoteController < ApplicationController
|
|||
note = check_user_return_note
|
||||
note.attributes = params["note"]
|
||||
if note.save
|
||||
render_partial 'notes', note
|
||||
render :partial => 'notes', :object => note
|
||||
else
|
||||
flash["warning"] = "Couldn't update note \"#{note.id.to_s}\""
|
||||
render_text ""
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ class NoteController < ApplicationController
|
|||
if @user == note.user
|
||||
return note
|
||||
else
|
||||
render_text ""
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class ProjectController < ApplicationController
|
|||
@page_title = "TRACKS::Project: #{@project.name}"
|
||||
|
||||
if @contexts.empty?
|
||||
flash['warning'] = 'You must add at least one context before adding next actions.'
|
||||
flash[:warning] = 'You must add at least one context before adding next actions.'
|
||||
end
|
||||
|
||||
if @not_done.empty?
|
||||
|
|
@ -108,10 +108,10 @@ class ProjectController < ApplicationController
|
|||
|
||||
# fallback for standard requests
|
||||
if @saved
|
||||
flash["notice"] = 'Added new next action.'
|
||||
flash[:notice] = 'Added new next action.'
|
||||
redirect_to :controller => 'todo', :action => 'index'
|
||||
else
|
||||
flash["warning"] = 'The next action was not added. Please try again.'
|
||||
flash[:warning] = 'The next action was not added. Please try again.'
|
||||
redirect_to :controller => 'todo', :action => 'index'
|
||||
end
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ class ProjectController < ApplicationController
|
|||
if request.xhr? # be sure to include an error.rjs
|
||||
render :action => 'error'
|
||||
else
|
||||
flash["warning"] = 'An error occurred on the server.'
|
||||
flash[:warning] = 'An error occurred on the server.'
|
||||
redirect_to :controller => 'todo', :action => 'index'
|
||||
end
|
||||
end
|
||||
|
|
@ -140,9 +140,9 @@ class ProjectController < ApplicationController
|
|||
return if request.xhr?
|
||||
|
||||
if @saved
|
||||
flash['notice'] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
else
|
||||
flash['notice'] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
end
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
|
|
@ -152,13 +152,13 @@ class ProjectController < ApplicationController
|
|||
def update
|
||||
self.init
|
||||
check_user_set_project
|
||||
@project.attributes = params["project"]
|
||||
@project.attributes = params['project']
|
||||
@project.name = deurlize(@project.name)
|
||||
if @project.save
|
||||
render_partial 'project_listing', @project
|
||||
render :partial => 'project_listing', :object => @project
|
||||
else
|
||||
flash["warning"] = "Couldn't update project"
|
||||
render_text ""
|
||||
flash[:warning] = "Couldn't update project"
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -178,9 +178,9 @@ class ProjectController < ApplicationController
|
|||
def destroy
|
||||
check_user_set_project
|
||||
if @project.destroy
|
||||
render_text ""
|
||||
render :text => ''
|
||||
else
|
||||
flash["warning"] = "Couldn't delete project \"#{@project.name}\""
|
||||
flash[:warning] = "Couldn't delete project \"#{@project.name}\""
|
||||
redirect_to( :controller => "project", :action => "list" )
|
||||
end
|
||||
end
|
||||
|
|
@ -210,8 +210,8 @@ class ProjectController < ApplicationController
|
|||
return @project
|
||||
else
|
||||
@project = nil # Should be nil anyway
|
||||
flash["warning"] = "Project and session user mis-match: #{@project.user_id} and #{@user.id}!"
|
||||
render_text ""
|
||||
flash[:warning] = "Project and session user mis-match: #{@project.user_id} and #{@user.id}!"
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -221,8 +221,8 @@ class ProjectController < ApplicationController
|
|||
return @project
|
||||
else
|
||||
@project = nil
|
||||
flash["warning"] = "Project and session user mis-match: #{@project.user_id} and #{@user.id}!"
|
||||
render_text ""
|
||||
flash[:warning] = "Project and session user mis-match: #{@project.user_id} and #{@user.id}!"
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -231,8 +231,8 @@ class ProjectController < ApplicationController
|
|||
if @user == item.user
|
||||
return item
|
||||
else
|
||||
flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!"
|
||||
render_text ""
|
||||
flash[:warning] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!"
|
||||
render :text => ''
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
class UserController < ApplicationController
|
||||
layout 'standard'
|
||||
prepend_before_filter :login_required
|
||||
|
||||
def index
|
||||
render_text "This will be our jumping-off point for managing user functions!"
|
||||
end
|
||||
|
||||
def admin
|
||||
render_text "You'll only be allowed to go here if you're an administrator."
|
||||
if Tracks::Config.auth_schemes.include?('open_id')
|
||||
open_id_consumer
|
||||
before_filter :begin_open_id_auth, :only => :update_auth_type
|
||||
end
|
||||
|
||||
verify :method => :post,
|
||||
|
|
@ -22,7 +18,7 @@ class UserController < ApplicationController
|
|||
#
|
||||
def create
|
||||
admin = User.find_admin
|
||||
#render_text "user is " + session["user_id"].to_s + " and admin is " + a.id.to_s
|
||||
#logger.debug "user is " + session["user_id"].to_s + " and admin is " + a.id.to_s
|
||||
unless session["user_id"].to_i == admin.id.to_i
|
||||
access_denied
|
||||
return
|
||||
|
|
@ -81,6 +77,71 @@ class UserController < ApplicationController
|
|||
redirect_to :controller => 'user', :action => 'change_password'
|
||||
end
|
||||
end
|
||||
|
||||
def change_auth_type
|
||||
@page_title = "TRACKS::Change authentication type"
|
||||
end
|
||||
|
||||
def update_auth_type
|
||||
if (params[:user][:auth_type] == 'open_id')
|
||||
case open_id_response.status
|
||||
when OpenID::SUCCESS
|
||||
# The URL was a valid identity URL. Now we just need to send a redirect
|
||||
# to the server using the redirect_url the library created for us.
|
||||
|
||||
# redirect to the server
|
||||
redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), url_for(:action => 'complete'))
|
||||
else
|
||||
flash[:warning] = "Unable to find openid server for <q>#{params[:openid_url]}</q>"
|
||||
redirect_to :action => 'change_auth_type'
|
||||
end
|
||||
return
|
||||
end
|
||||
@user.auth_type = params[:user][:auth_type]
|
||||
if @user.save
|
||||
flash[:notice] = "Authentication type updated."
|
||||
redirect_to :controller => 'user', :action => 'preferences'
|
||||
else
|
||||
flash[:warning] = "There was a problem updating your authentication type: #{ @user.errors.full_messages.join(', ')}"
|
||||
redirect_to :controller => 'user', :action => 'change_auth_type'
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
case open_id_response.status
|
||||
when OpenID::FAILURE
|
||||
# In the case of failure, if info is non-nil, it is the
|
||||
# URL that we were verifying. We include it in the error
|
||||
# message to help the user figure out what happened.
|
||||
if open_id_response.identity_url
|
||||
flash[:message] = "Verification of #{open_id_response.identity_url} failed. "
|
||||
else
|
||||
flash[:message] = "Verification failed. "
|
||||
end
|
||||
flash[:message] += open_id_response.msg.to_s
|
||||
|
||||
when OpenID::SUCCESS
|
||||
# Success means that the transaction completed without
|
||||
# error. If info is nil, it means that the user cancelled
|
||||
# the verification.
|
||||
@user.auth_type = 'open_id'
|
||||
@user.open_id_url = open_id_response.identity_url
|
||||
if @user.save
|
||||
flash[:message] = "You have successfully verified #{open_id_response.identity_url} as your identity and set your authentication type to Open ID."
|
||||
else
|
||||
flash[:warning] = "You have successfully verified #{open_id_response.identity_url} as your identity but there was a problem saving your authentication preferences."
|
||||
end
|
||||
redirect_to :action => 'preferences'
|
||||
|
||||
when OpenID::CANCEL
|
||||
flash[:message] = "Verification cancelled."
|
||||
|
||||
else
|
||||
flash[:warning] = "Unknown response status: #{open_id_response.status}"
|
||||
end
|
||||
redirect_to :action => 'change_auth_type' unless performed?
|
||||
end
|
||||
|
||||
|
||||
def refresh_token
|
||||
@user.crypt_word
|
||||
|
|
@ -93,10 +154,10 @@ class UserController < ApplicationController
|
|||
def do_change_password_for(user)
|
||||
user.change_password(params[:updateuser][:password], params[:updateuser][:password_confirmation])
|
||||
if user.save
|
||||
flash["notice"] = "Password updated."
|
||||
flash[:notice] = "Password updated."
|
||||
return true
|
||||
else
|
||||
flash["warning"] = 'There was a problem saving the password. Please retry.'
|
||||
flash[:warning] = 'There was a problem saving the password. Please retry.'
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -140,4 +140,8 @@ module ApplicationHelper
|
|||
link_to( descriptor, { :controller => "project", :action => "show", :name => urlize(item.project.name) }, :title => "View project: #{item.project.name}" )
|
||||
end
|
||||
|
||||
def render_flash
|
||||
render :partial => 'shared/flash'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,17 +10,20 @@ class User < ActiveRecord::Base
|
|||
attr_protected :is_admin
|
||||
|
||||
def self.authenticate(login, pass)
|
||||
find_first(["login = ? AND password = ?", login, sha1(pass)])
|
||||
candidate = find(:first, :conditions => ["login = ?", login])
|
||||
return nil if candidate.nil?
|
||||
if candidate.auth_type == 'database'
|
||||
return candidate if candidate.password == sha1(pass)
|
||||
elsif candidate.auth_type == 'ldap' && Tracks::Config.auth_schemes.include?('ldap')
|
||||
return candidate if SimpleLdapAuthenticator.valid?(login, pass)
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def self.find_admin
|
||||
find_first([ "is_admin = ?", true ])
|
||||
end
|
||||
|
||||
def self.get_salt
|
||||
SALT
|
||||
end
|
||||
|
||||
def display_name
|
||||
if first_name.blank? && last_name.blank?
|
||||
return login
|
||||
|
|
@ -44,7 +47,7 @@ class User < ActiveRecord::Base
|
|||
protected
|
||||
|
||||
def self.sha1(pass)
|
||||
Digest::SHA1.hexdigest("#{get_salt}--#{pass}--")
|
||||
Digest::SHA1.hexdigest("#{Tracks::Config.salt}--#{pass}--")
|
||||
end
|
||||
|
||||
before_create :crypt_password, :crypt_word
|
||||
|
|
@ -54,10 +57,12 @@ protected
|
|||
write_attribute("password", self.class.sha1(password)) if password == @password_confirmation
|
||||
end
|
||||
|
||||
validates_presence_of :password, :login
|
||||
validates_presence_of :login
|
||||
validates_presence_of :password, :if => Proc.new{|user| user.auth_type == 'database'}
|
||||
validates_length_of :password, :within => 5..40
|
||||
validates_confirmation_of :password
|
||||
validates_length_of :login, :within => 3..80
|
||||
validates_uniqueness_of :login, :on => :create
|
||||
|
||||
validates_inclusion_of :auth_type, :in => Tracks::Config.auth_schemes, :message=>"not a valid authentication type"
|
||||
validates_presence_of :open_id_url, :if => Proc.new{|user| user.auth_type == 'open_id'}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
:update => "container_#{context.id}",
|
||||
:complete => visual_effect(:appear, 'container_#{context.id}') %>
|
||||
<table style="table-layout: fixed;" width="450">
|
||||
<%= render_partial 'context_form', context %>
|
||||
<%= render :partial => 'context_form', :object => context %>
|
||||
<tr>
|
||||
<td width="150"> </td>
|
||||
<td width="300"><input type="submit" value="Update" /> <a href="javascript:void(0);" onclick="Element.toggle('context-<%= context.id %>','context-<%= context.id %>-edit-form');Form.reset('form-context-<%= context.id %>');">Cancel</a></td>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
<div id="display_box">
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<div id="<%= name %>"<%= flash[name] ? "" : " style=\"display:none\""%>><%= flash[name] %></div>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<div id="list-contexts">
|
||||
<% for context in @contexts %>
|
||||
<%= render_partial( 'context_listing', context ) %>
|
||||
<% end %>
|
||||
<%= render :partial => 'context_listing', :collection => @contexts %>
|
||||
</div>
|
||||
|
||||
<%= sortable_element 'list-contexts', get_listing_sortable_options %>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= render :partial => "context/context", :locals => { :context => @context, :collapsible => false } %>
|
||||
<% unless @done.empty? -%>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= render :partial => "items" %>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
|
|
|
|||
|
|
@ -1,29 +1,22 @@
|
|||
<%= start_form_tag :action=> "login" %>
|
||||
|
||||
<% auth_schemes = Tracks::Config.auth_schemes -%>
|
||||
<div title="Account login" id="loginform" class="form">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<h3>Please log in to use Tracks:</h3>
|
||||
|
||||
<% if @message %>
|
||||
<div id="message"><%= @message %></div>
|
||||
<% end %>
|
||||
<h3>Please log in to use Tracks:</h3>
|
||||
|
||||
<% if auth_schemes.include?('database') || auth_schemes.include?('open_id') %>
|
||||
<%= start_form_tag :action=> 'login' %>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="100px"><label for="user_login">Login:</label></td>
|
||||
<td width="100px"><input type="text" name="user_login" id="user_login" size="20" value=""/></td>
|
||||
<td width="100px"><input type="text" name="user_login" id="user_login" value="" class="login_text" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100px"><label for="user_password">Password:</label></td>
|
||||
<td width="100px"><input type="password" name="user_password" id="user_password" size="20"/></td>
|
||||
<td width="100px"><input type="password" name="user_password" id="user_password" class="login_text" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td width="100px"><label for="user_noexpiry">Stay logged in:</label></td>
|
||||
<td width="100px"><input type="checkbox" name="user_noexpiry" id="user_noexpiry" checked /></td>
|
||||
</tr>
|
||||
|
|
@ -32,8 +25,28 @@
|
|||
<td><input type="submit" name="login" value="Login »" class="primary" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<%= end_form_tag %>
|
||||
<% end %>
|
||||
|
||||
<% if auth_schemes.include?('open_id') %>
|
||||
<%= start_form_tag :action=> 'login', :action => 'begin' %>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="100px"><label for="openid_url">Identity URL:</label></td>
|
||||
<td width="100px"><input type="text" name="openid_url" id="openid_url" value="" class="login_text open_id" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100px"><label for="user_noexpiry">Stay logged in:</label></td>
|
||||
<td width="100px"><input type="checkbox" name="user_noexpiry" id="user_noexpiry" checked /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100px"></td>
|
||||
<td><input type="submit" name="login" value="Verify »" class="primary" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
<%= end_form_tag %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<%= end_form_tag %>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@
|
|||
|
||||
<%= error_messages_for 'user' %><br/>
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<h3><%= @page_title -%></h3>
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
:html => { :id => "form-note-#{note.id}", :class => "inline-form" },
|
||||
:update => "note-#{note.id}-container",
|
||||
:complete => visual_effect(:appear, "note-#{note.id}-container") %>
|
||||
<%= render_partial "note_edit_form", note %>
|
||||
<%= render :partial => "note_edit_form", :object => note %>
|
||||
<%= end_form_tag %>
|
||||
</div><!-- [end:action-item.id-edit-form] -->
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<% else -%>
|
||||
<% for notes in @all_notes -%>
|
||||
<div class="container" id="note-<%= notes.id %>-wrapper">
|
||||
<%= render_partial "notes", notes %>
|
||||
<%= render :partial => 'notes', :object => notes %>
|
||||
</div>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div id="display_box_projects">
|
||||
<div class="container" id="note-<%= @note.id %>-wrapper">
|
||||
<%= render_partial "notes", @note %>
|
||||
<%= render :partial => 'notes', :object => @note %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
:update => "container_#{project.id}",
|
||||
:complete => visual_effect(:appear, 'container_#{project.id}') %>
|
||||
<table style="table-layout: fixed;" width="450">
|
||||
<%= render_partial 'project_form', project %>
|
||||
<%= render :partial => 'project_form', :object => project %>
|
||||
<tr>
|
||||
<td width="150"> </td>
|
||||
<td width="300"><input type="submit" value="Update" /> <a href="javascript:void(0);" onclick="Element.toggle('project-<%= project.id %>','project-<%= project.id %>-edit-form');Form.reset('form-project-<%= project.id %>');">Cancel</a></td>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
:html => { :id => "form-action-#{item.id}", :class => "inline-form" },
|
||||
:update => "item-#{item.id}-container",
|
||||
:complete => visual_effect(:appear, "item-#{item.id}-container") %>
|
||||
<%= render_partial 'todo/action_edit_form', item %>
|
||||
<%= render :partial => 'todo/action_edit_form', :object => item %>
|
||||
<%= end_form_tag %>
|
||||
</div><!-- [end:action-item.id-edit-form] -->
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
<div id="display_box">
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<div id="<%= name %>"<%= flash[name] ? "" : " style=\"display:none\""%>><%= flash[name] %></div>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<div id="list-projects">
|
||||
<% for project in @projects %>
|
||||
<%= render_partial( 'project_listing', project ) %>
|
||||
<% end %>
|
||||
<%= render :partial => 'project_listing', :collection => @projects %>
|
||||
</div>
|
||||
<%= sortable_element 'list-projects', get_listing_sortable_options %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= render :partial => "project/project", :locals => { :project => @project, :collapsible => false } %>
|
||||
<% unless @done.empty? -%>
|
||||
|
|
|
|||
7
tracks/app/views/shared/_flash.rhtml
Normal file
7
tracks/app/views/shared/_flash.rhtml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<% for flash_key in [:notice, :warning, :message] %>
|
||||
<% if flash.has_key?(flash_key) %>
|
||||
<div id="<%= flash_key %>"><%= flash[flash_key] %></div>
|
||||
<% else%>
|
||||
<div id="<%= flash_key %>" style="display:none"><%= flash[flash_key] %></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
page["form-action-#{@item.id}"].replace_html :partial => 'todo/edit_form'
|
||||
page["item-#{@item.id}"].hide
|
||||
page["action-#{@item.id}-edit-form"].show
|
||||
page.visual_effect :appear, "action-#{@item.id}-edit-form", :duration => 0.2
|
||||
page.call "Form.focusFirstElement", "form-action-#{@item.id}"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= render :partial => "context/context", :collection => @contexts_to_show,
|
||||
:locals => { :collapsible => true } %>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
<div id="display_box">
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= render :partial => "tickler_items" %>
|
||||
|
||||
|
|
|
|||
20
tracks/app/views/user/change_auth_type.rhtml
Normal file
20
tracks/app/views/user/change_auth_type.rhtml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<div id="single_box" class="container context authtype_container">
|
||||
|
||||
<h2>Change authentication type</h2>
|
||||
|
||||
<%= render_flash %>
|
||||
|
||||
<%= error_messages_for 'user' %>
|
||||
|
||||
<p>Select your new authentication type and click 'Change Authentication Type' to replace your current settings.</p>
|
||||
|
||||
<%= start_form_tag :action => 'update_auth_type' %>
|
||||
<div><label for="user_auth_type">Authentication type:</label> <%= select('user', 'auth_type', Tracks::Config.auth_schemes.collect {|p| [ p, p ] }) %></div>
|
||||
<div id="open_id" style="display:<%= @user.auth_type == 'open_id' ? 'block' : 'none' %>"><label for="user_open_id_url">Identity URL:</label> <input type="text" name="openid_url" value="<%= @user.open_id_url %>" class="open_id" /></div>
|
||||
<div class="actions"><%= submit_tag 'Change Authentication Type' %> <%= link_to 'Cancel', :action => 'preferences' %></div>
|
||||
|
||||
<%= observe_field( :user_auth_type, :function => "$('open_id').style.display = value == 'open_id' ? 'block' : 'none'") %>
|
||||
|
||||
<%= end_form_tag %>
|
||||
|
||||
</div>
|
||||
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
<h2><%= @page_title %></h2>
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render_flash %>
|
||||
|
||||
<%= error_messages_for 'user' %>
|
||||
<%= error_messages_for 'user' %>
|
||||
|
||||
<p>Enter your new password in the fields below and click 'Change Password' to replace your current password with your new one (note that this will also change the URL you use to subscribe to your RSS or text field).</p>
|
||||
<p>Enter your new password in the fields below and click 'Change Password' to replace your current password with your new one.</p>
|
||||
|
||||
<%= start_form_tag :action => 'update_password' %>
|
||||
<table width="440px">
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
<div id="single_box" class="container context">
|
||||
<div id="single_box" class="container context prefscontainer">
|
||||
|
||||
<%= render_flash %>
|
||||
|
||||
<h2>Your preferences</h2>
|
||||
|
||||
<% for name in ["notice", "warning", "message"] %>
|
||||
<% if flash[name] %>
|
||||
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<ul id="prefs">
|
||||
<li>First name: <span class="highlight"><%= @user.first_name %></span></li>
|
||||
<li>Last name: <span class="highlight"><%= @user.last_name %></span></li>
|
||||
|
|
@ -30,16 +26,37 @@
|
|||
<li>Refresh interval (in minutes): <span class="highlight"><%= @prefs.refresh %></span></li>
|
||||
<li>Verbose action descriptors: <span class="highlight"><%= @prefs.verbose_action_descriptors %></span></li>
|
||||
</ul>
|
||||
<%= link_to "Edit preferences", :controller => 'user', :action => 'edit_preferences' %> |
|
||||
<%= link_to 'Change password', :controller => 'user', :action => 'change_password' %>
|
||||
<div class="actions">
|
||||
<%= link_to "Edit preferences »", { :controller => 'user', :action => 'edit_preferences'}, :class => 'edit_link' %>
|
||||
</div>
|
||||
|
||||
<h2>Your token</h2>
|
||||
<div id="token_area">
|
||||
<div class="description">Token (for feeds and API use):</div>
|
||||
<div id="token><span class="highlight"><%= @user.word %></span></div>
|
||||
<div class="token_regenerate">
|
||||
<%= button_to "Generate a new token", { :controller => 'user', :action => 'refresh_token'},
|
||||
:confirm => "Are you sure? Generating a new token will replace the existing one and break any external usages of this token." %>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
<div class="description">Token (for feeds and API use):</div>
|
||||
<div id="token><span class="highlight"><%= @user.word %></span></div>
|
||||
<div class="token_regenerate">
|
||||
<%= button_to "Generate a new token", { :controller => 'user', :action => 'refresh_token'},
|
||||
:confirm => "Are you sure? Generating a new token will replace the existing one and break any external usages of this token." %>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Your authentication</h2>
|
||||
<div id="authentication_area">
|
||||
<% if Tracks::Config.auth_schemes.length > 1 %>
|
||||
<p>Your authentication type is <span class="highlight"><%= @user.auth_type %></span>.
|
||||
<div class="actions">
|
||||
<%= link_to "Change your authentication type »", { :controller => 'user', :action => 'change_auth_type'}, :class => 'edit_link' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @user.auth_type == 'database' %>
|
||||
<div class="actions">
|
||||
<%= link_to 'Change your password »', :controller => 'user', :action => 'change_password' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @user.auth_type == 'open_id' %>
|
||||
<p>Your Open ID URL is <span class="highlight"><%= @user.open_id_url %></span>.
|
||||
<div class="actions">
|
||||
<%= link_to 'Change Your Identity URL »', :controller => 'user', :action => 'change_auth_type' %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -60,9 +60,23 @@ SALT = "change-me"
|
|||
|
||||
require 'acts_as_namepart_finder'
|
||||
require 'acts_as_todo_container'
|
||||
require 'config'
|
||||
|
||||
ActiveRecord::Base.class_eval do
|
||||
include Tracks::Acts::NamepartFinder
|
||||
include Tracks::Acts::TodoContainer
|
||||
end
|
||||
|
||||
AUTHENTICATION_SCHEMES = ['database'] #one or more of ['database', 'ldap', 'open_id']
|
||||
if (AUTHENTICATION_SCHEMES.include? 'ldap')
|
||||
require 'net/ldap' #requires ruby-net-ldap gem be installed
|
||||
require 'simple_ldap_authenticator'
|
||||
SimpleLdapAuthenticator.ldap_library = 'net/ldap'
|
||||
SimpleLdapAuthenticator.servers = %w'localhost'
|
||||
SimpleLdapAuthenticator.use_ssl = false
|
||||
SimpleLdapAuthenticator.login_format = 'cn=%s,dc=example,dc=com'
|
||||
end
|
||||
if (AUTHENTICATION_SCHEMES.include? 'open_id')
|
||||
#requires ruby-openid gem to be installed
|
||||
end
|
||||
|
||||
|
|
|
|||
9
tracks/db/migrate/016_add_user_auth_type.rb
Normal file
9
tracks/db/migrate/016_add_user_auth_type.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class AddUserAuthType < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :users, :auth_type, :string, :default => 'database', :null => false
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :users, :auth_type
|
||||
end
|
||||
end
|
||||
45
tracks/db/migrate/017_add_open_id_tables.rb
Normal file
45
tracks/db/migrate/017_add_open_id_tables.rb
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# 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 AddOpenIdTables < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table "open_id_associations", :force => true do |t|
|
||||
t.column "server_url", :binary
|
||||
t.column "handle", :string
|
||||
t.column "secret", :binary
|
||||
t.column "issued", :integer
|
||||
t.column "lifetime", :integer
|
||||
t.column "assoc_type", :string
|
||||
end
|
||||
|
||||
create_table "open_id_nonces", :force => true do |t|
|
||||
t.column "nonce", :string
|
||||
t.column "created", :integer
|
||||
end
|
||||
|
||||
create_table "open_id_settings", :force => true do |t|
|
||||
t.column "setting", :string
|
||||
t.column "value", :binary
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table "open_id_associations"
|
||||
drop_table "open_id_nonces"
|
||||
drop_table "open_id_settings"
|
||||
end
|
||||
end
|
||||
9
tracks/db/migrate/018_add_user_open_id_url.rb
Normal file
9
tracks/db/migrate/018_add_user_open_id_url.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class AddUserOpenIdUrl < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :users, :open_id_url, :string
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :users, :open_id_url
|
||||
end
|
||||
end
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
# migrations feature of ActiveRecord to incrementally modify your database, and
|
||||
# then regenerate this schema definition.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 15) do
|
||||
ActiveRecord::Schema.define(:version => 18) do
|
||||
|
||||
create_table "contexts", :force => true do |t|
|
||||
t.column "name", :string, :default => "", :null => false
|
||||
|
|
@ -19,6 +19,25 @@ ActiveRecord::Schema.define(:version => 15) do
|
|||
t.column "updated_at", :datetime
|
||||
end
|
||||
|
||||
create_table "open_id_associations", :force => true do |t|
|
||||
t.column "server_url", :binary
|
||||
t.column "handle", :string
|
||||
t.column "secret", :binary
|
||||
t.column "issued", :integer
|
||||
t.column "lifetime", :integer
|
||||
t.column "assoc_type", :string
|
||||
end
|
||||
|
||||
create_table "open_id_nonces", :force => true do |t|
|
||||
t.column "nonce", :string
|
||||
t.column "created", :integer
|
||||
end
|
||||
|
||||
create_table "open_id_settings", :force => true do |t|
|
||||
t.column "setting", :string
|
||||
t.column "value", :binary
|
||||
end
|
||||
|
||||
create_table "preferences", :force => true do |t|
|
||||
t.column "user_id", :integer, :default => 0, :null => false
|
||||
t.column "date_format", :string, :limit => 40, :default => "%d/%m/%Y", :null => false
|
||||
|
|
@ -70,6 +89,8 @@ ActiveRecord::Schema.define(:version => 15) do
|
|||
t.column "is_admin", :integer, :limit => 4, :default => 0, :null => false
|
||||
t.column "first_name", :string
|
||||
t.column "last_name", :string
|
||||
t.column "auth_type", :string, :default => "database", :null => false
|
||||
t.column "open_id_url", :string
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
15
tracks/lib/config.rb
Normal file
15
tracks/lib/config.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
module Tracks
|
||||
|
||||
class Config
|
||||
|
||||
def self.salt
|
||||
SALT
|
||||
end
|
||||
|
||||
def self.auth_schemes
|
||||
AUTHENTICATION_SCHEMES
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
BIN
tracks/public/images/open-id-login-bg.gif
Normal file
BIN
tracks/public/images/open-id-login-bg.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 237 B |
|
|
@ -132,4 +132,15 @@ div.memo {
|
|||
#errorExplanation ul li {
|
||||
font-size: 1em;
|
||||
list-style: disc;
|
||||
}
|
||||
input.login_text {
|
||||
width:200px;
|
||||
}
|
||||
input.open_id {
|
||||
background: url(../images/open-id-login-bg.gif) no-repeat;
|
||||
background-color: #fff;
|
||||
background-position: 0 50%;
|
||||
color: #000;
|
||||
padding-left: 18px;
|
||||
width:182px;
|
||||
}
|
||||
|
|
@ -643,9 +643,10 @@ div.message {
|
|||
}
|
||||
|
||||
ul#prefs {list-style-type: disc; margin-left: 5px;}
|
||||
#token_area {
|
||||
#token_area, #authentication_area {
|
||||
text-align:center;
|
||||
margin-top:20px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
#token_area .description{
|
||||
font-weight:bold;
|
||||
|
|
@ -654,7 +655,14 @@ ul#prefs {list-style-type: disc; margin-left: 5px;}
|
|||
width:100%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.prefscontainer .actions {
|
||||
text-align:center;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
.authtype_container .actions {
|
||||
margin-top:20px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
#feedlegend {
|
||||
padding: 2px;
|
||||
border: 1px solid #CCC;
|
||||
|
|
@ -688,3 +696,11 @@ ul#prefs {list-style-type: disc; margin-left: 5px;}
|
|||
font-weight: normal;
|
||||
font-style:oblique;
|
||||
}
|
||||
input.open_id {
|
||||
background: url(../images/open-id-login-bg.gif) no-repeat;
|
||||
background-color: #fff;
|
||||
background-position: 0 50%;
|
||||
color: #000;
|
||||
padding-left: 18px;
|
||||
width:182px;
|
||||
}
|
||||
16
tracks/test/fixtures/users.yml
vendored
16
tracks/test/fixtures/users.yml
vendored
|
|
@ -2,17 +2,29 @@
|
|||
admin_user:
|
||||
id: 1
|
||||
login: admin
|
||||
password: <%= Digest::SHA1.hexdigest("#{User.get_salt()}--abracadabra--") %>
|
||||
password: <%= Digest::SHA1.hexdigest("#{Tracks::Config.salt}--abracadabra--") %>
|
||||
word: <%= Digest::SHA1.hexdigest("adminSat Feb 25 17:14:00 GMT 20060.236961325863376") %>
|
||||
is_admin: true
|
||||
first_name: Admin
|
||||
last_name: Schmadmin
|
||||
auth_type: database
|
||||
|
||||
other_user:
|
||||
id: 2
|
||||
login: jane
|
||||
password: <%= Digest::SHA1.hexdigest("#{User.get_salt()}--sesame--") %>
|
||||
password: <%= Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--") %>
|
||||
word: <%= Digest::SHA1.hexdigest("janeSun Feb 19 14:42:45 GMT 20060.408173979260027") %>
|
||||
is_admin: false
|
||||
first_name: Jane
|
||||
last_name: Doe
|
||||
auth_type: database
|
||||
|
||||
ldap_user:
|
||||
id: 3
|
||||
login: john
|
||||
password:
|
||||
word: <%= Digest::SHA1.hexdigest("johnSun Feb 19 14:42:45 GMT 20060.408173979260027") %>
|
||||
is_admin: false
|
||||
first_name: John
|
||||
last_name: Deere
|
||||
auth_type: ldap
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class BackendControllerTest < Test::Unit::TestCase
|
|||
def setup
|
||||
@controller = BackendController.new
|
||||
request, response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
||||
assert_equal "change-me", User.get_salt()
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
end
|
||||
|
||||
def test_new_todo_fails_with_incorrect_token
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
|
||||
def setup
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", User.get_salt()
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
@controller = LoginController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@num_users_in_fixture = User.count
|
||||
end
|
||||
|
||||
#============================================
|
||||
|
|
@ -33,7 +34,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert_equal user.id, @response.session['user_id']
|
||||
assert_equal user.login, "admin"
|
||||
assert user.is_admin
|
||||
assert_equal "Login successful: session will not expire.", flash['notice']
|
||||
assert_equal "Login successful: session will not expire.", flash[:notice]
|
||||
assert_redirect_url "http://#{@request.host}/bogus/location"
|
||||
end
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert_equal user.id, @response.session['user_id']
|
||||
assert_equal user.login, "jane"
|
||||
assert user.is_admin == false || user.is_admin == 0
|
||||
assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash['notice']
|
||||
assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash[:notice]
|
||||
assert_redirected_to :controller => 'todo', :action => 'index'
|
||||
end
|
||||
|
||||
|
|
@ -59,14 +60,14 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
def test_login_bad_password
|
||||
post :login, {:user_login => 'jane', :user_password => 'wrong', :user_noexpiry => 'on'}
|
||||
assert_session_has_no :user
|
||||
assert_equal "Login unsuccessful", flash['warning']
|
||||
assert_equal "Login unsuccessful", flash[:warning]
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_login_bad_login
|
||||
post :login, {:user_login => 'blah', :user_password => 'sesame', :user_noexpiry => 'on'}
|
||||
assert_session_has_no :user
|
||||
assert_equal "Login unsuccessful", flash['warning']
|
||||
assert_equal "Login unsuccessful", flash[:warning]
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
admin = login('admin', 'abracadabra', 'on')
|
||||
assert admin.is_admin
|
||||
newbie = create('newbie', 'newbiepass')
|
||||
assert_equal "Signup successful for user newbie.", flash['notice']
|
||||
assert_equal "Signup successful for user newbie.", flash[:notice]
|
||||
assert_redirected_to :controller => 'todo', :action => 'index'
|
||||
assert_valid newbie
|
||||
get :logout # logout the admin user
|
||||
|
|
@ -92,8 +93,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert_redirected_to :controller => 'todo', :action => 'index'
|
||||
assert_equal 'newbie', user.login
|
||||
assert user.is_admin == false || user.is_admin == 0
|
||||
num_users = User.find(:all)
|
||||
assert_equal num_users.length, 3
|
||||
assert_equal User.count, @num_users_in_fixture + 1
|
||||
end
|
||||
|
||||
# Test whether signup of new users is denied to a non-admin user
|
||||
|
|
@ -103,9 +103,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert non_admin.is_admin == false || non_admin.is_admin == 0
|
||||
post :signup, :user => {:login => 'newbie2', :password => 'newbiepass2', :password_confirmation => 'newbiepass2'}
|
||||
assert_template 'login/nosignup'
|
||||
|
||||
num_users = User.find(:all)
|
||||
assert_equal num_users.length, 2
|
||||
assert_number_of_users_is_unchanged
|
||||
end
|
||||
|
||||
# ============================================
|
||||
|
|
@ -117,8 +115,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert admin.is_admin
|
||||
assert_equal admin.id, @response.session['user_id']
|
||||
post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''}
|
||||
num_users = User.find(:all)
|
||||
assert_equal num_users.length, 2
|
||||
assert_number_of_users_is_unchanged
|
||||
assert_redirected_to :controller => 'login', :action => 'signup'
|
||||
end
|
||||
|
||||
|
|
@ -127,8 +124,7 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert admin.is_admin
|
||||
assert_equal admin.id, @response.session['user_id']
|
||||
post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
|
||||
num_users = User.find(:all)
|
||||
assert_equal num_users.length, 2
|
||||
assert_number_of_users_is_unchanged
|
||||
assert_redirected_to :controller => 'login', :action => 'signup'
|
||||
end
|
||||
|
||||
|
|
@ -140,8 +136,13 @@ class LoginControllerTest < Test::Unit::TestCase
|
|||
assert_equal admin.id, @response.session['user_id']
|
||||
post :create, :user => {:login => 'jane', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
|
||||
num_users = User.find(:all)
|
||||
assert_equal num_users.length, 2
|
||||
assert_number_of_users_is_unchanged
|
||||
assert_redirected_to :controller => 'login', :action => 'signup'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_number_of_users_is_unchanged
|
||||
assert_equal User.count, @num_users_in_fixture
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,32 +10,12 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
|
||||
def setup
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", User.get_salt()
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
@controller = UserController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Test index with and without login
|
||||
#
|
||||
def test_index
|
||||
get :index # should fail because no login
|
||||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
@request.session['user_id'] = users(:admin_user).id # log in the admin user
|
||||
get :index
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
# Test admin with and without login
|
||||
#
|
||||
def test_admin
|
||||
get :admin # should fail because no login
|
||||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
@request.session['user_id'] = users(:admin_user).id # log in the admin user
|
||||
get :admin
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_preferences
|
||||
get :preferences # should fail because no login
|
||||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
|
|
@ -81,8 +61,8 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
post :update_password, :updateuser => {:password => 'newpassword', :password_confirmation => 'newpassword'}
|
||||
assert_redirected_to :controller => 'user', :action => 'preferences'
|
||||
@updated_user = User.find(users(:admin_user).id)
|
||||
assert_equal @updated_user.password, Digest::SHA1.hexdigest("#{User.get_salt()}--newpassword--")
|
||||
assert_equal flash['notice'], "Password updated."
|
||||
assert_equal @updated_user.password, Digest::SHA1.hexdigest("#{Tracks::Config.salt}--newpassword--")
|
||||
assert_equal flash[:notice], "Password updated."
|
||||
end
|
||||
|
||||
def test_update_password_no_confirmation
|
||||
|
|
@ -92,7 +72,7 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
post :update_password, :updateuser => {:password => 'newpassword', :password_confirmation => 'wrong'}
|
||||
assert_redirected_to :controller => 'user', :action => 'change_password'
|
||||
assert users(:admin_user).save, false
|
||||
assert_equal flash['warning'], 'There was a problem saving the password. Please retry.'
|
||||
assert_equal flash[:warning], 'There was a problem saving the password. Please retry.'
|
||||
end
|
||||
|
||||
def test_update_password_validation_errors
|
||||
|
|
@ -105,7 +85,7 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
# For some reason, no errors are being raised now.
|
||||
#assert_equal 1, users(:admin_user).errors.count
|
||||
#assert_equal users(:admin_user).errors.on(:password), "is too short (min is 5 characters)"
|
||||
assert_equal flash['warning'], 'There was a problem saving the password. Please retry.'
|
||||
assert_equal flash[:warning], 'There was a problem saving the password. Please retry.'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class CreateUserControllerTest < ActionController::IntegrationTest
|
|||
fixtures :users
|
||||
|
||||
@@foobar_postdata = "<request><login>foo</login><password>bar</password></request>"
|
||||
@@john_postdata = "<request><login>john</login><password>barracuda</password></request>"
|
||||
@@johnny_postdata = "<request><login>johnny</login><password>barracuda</password></request>"
|
||||
|
||||
def setup
|
||||
assert_test_environment_ok
|
||||
|
|
@ -63,13 +63,13 @@ class CreateUserControllerTest < ActionController::IntegrationTest
|
|||
|
||||
def test_creates_new_user
|
||||
initial_count = User.count
|
||||
authenticated_post_xml_to_user_create @@john_postdata
|
||||
authenticated_post_xml_to_user_create @@johnny_postdata
|
||||
assert_response_and_body 200, "User created."
|
||||
assert_equal initial_count + 1, User.count
|
||||
john1 = User.find_by_login('john')
|
||||
assert_not_nil john1, "expected user john to be created"
|
||||
john2 = User.authenticate('john','barracuda')
|
||||
assert_not_nil john2, "expected user john to be created"
|
||||
johnny1 = User.find_by_login('johnny')
|
||||
assert_not_nil johnny1, "expected user johnny to be created"
|
||||
johnny2 = User.authenticate('johnny','barracuda')
|
||||
assert_not_nil johnny2, "expected user johnny to be created"
|
||||
end
|
||||
|
||||
def test_fails_with_get_verb
|
||||
|
|
|
|||
117
tracks/test/integration/ldap_auth_test.rb
Executable file
117
tracks/test/integration/ldap_auth_test.rb
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
require "#{File.dirname(__FILE__)}/../test_helper"
|
||||
require 'tempfile'
|
||||
require 'user'
|
||||
|
||||
class LdapAuthTest < Test::Unit::TestCase
|
||||
|
||||
fixtures :users
|
||||
|
||||
SLAPD_BIN = "/usr/libexec/slapd" #You may need to adjust this
|
||||
SLAPD_SCHEMA_DIR = "/etc/openldap/schema/" #You may need to adjust this
|
||||
SLAPD_TEST_PORT = 10389
|
||||
OUTPUT_DEBUG_INFO = false
|
||||
|
||||
def setup
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
|
||||
setup_ldap_server_conf
|
||||
start_ldap_server
|
||||
end
|
||||
|
||||
def teardown
|
||||
stop_ldap_server
|
||||
end
|
||||
|
||||
def test_authenticate_against_ldap
|
||||
add_ldap_user_to_ldap_repository
|
||||
user = User.authenticate('john', 'deere')
|
||||
assert_not_nil(user)
|
||||
assert_equal user.login, 'john'
|
||||
end
|
||||
|
||||
def setup_ldap_server_conf
|
||||
@slapd_conf = create_slapd_conf()
|
||||
open(@slapd_conf.path) { |f| f.read }
|
||||
unless File.exist?(SLAPD_BIN)
|
||||
assert false, "slapd could not be found at #{SLAPD_BIN}. Adjust the path in #{__FILE__}"
|
||||
end
|
||||
end
|
||||
|
||||
def start_ldap_server
|
||||
t = Thread.new(@slapd_conf.path) { |slapd_conf_path|
|
||||
puts "starting slapd..." if OUTPUT_DEBUG_INFO
|
||||
run_cmd %Q{/usr/libexec/slapd -f #{slapd_conf_path} -h "ldap://127.0.0.1:10389/"}
|
||||
}
|
||||
sleep(2)
|
||||
run_cmd %Q{ldapsearch -H "ldap://127.0.0.1:10389/" -x -b '' -s base '(objectclass=*)' namingContexts}
|
||||
end
|
||||
|
||||
def add_ldap_user_to_ldap_repository
|
||||
ldif_file = create_ldif()
|
||||
run_cmd %Q{ldapadd -H "ldap://127.0.0.1:10389/" -f #{ldif_file.path} -cxv -D "cn=Manager,dc=lukemelia,dc=com" -w secret}
|
||||
puts `cat #{ldif_file.path}` if OUTPUT_DEBUG_INFO
|
||||
end
|
||||
|
||||
def stop_ldap_server
|
||||
pid = open(get_pid_file_path(@slapd_conf)) { |f| f.read }
|
||||
run_cmd "kill -TERM #{pid}"
|
||||
end
|
||||
|
||||
def create_slapd_conf
|
||||
slapd_conf = Tempfile.new("slapd.conf")
|
||||
slapd_conf.path
|
||||
data_dir = slapd_conf.path + '-data'
|
||||
pid_file = get_pid_file_path(slapd_conf)
|
||||
Dir.mkdir(data_dir)
|
||||
encrypted_password = `slappasswd -s secret`
|
||||
open(slapd_conf.path, 'w') do |f|
|
||||
f.puts %Q{include #{SLAPD_SCHEMA_DIR}core.schema
|
||||
pidfile #{pid_file}
|
||||
database ldbm
|
||||
suffix "dc=lukemelia,dc=com"
|
||||
rootdn "cn=Manager,dc=lukemelia,dc=com"
|
||||
rootpw #{encrypted_password}
|
||||
directory #{data_dir}
|
||||
|
||||
access to *
|
||||
by self write
|
||||
by users read
|
||||
by anonymous auth
|
||||
}
|
||||
end
|
||||
puts `cat #{slapd_conf.path}` if OUTPUT_DEBUG_INFO
|
||||
slapd_conf
|
||||
end
|
||||
|
||||
def create_ldif
|
||||
ldif_file = Tempfile.new("ldap_user.ldif")
|
||||
encrypted_password = `slappasswd -s deere`
|
||||
open(ldif_file.path, 'w') do |f|
|
||||
f.puts %Q{dn: dc=lukemelia,dc=com
|
||||
objectclass: dcObject
|
||||
objectclass: organization
|
||||
o: Luke Melia DotCom
|
||||
dc: lukemelia
|
||||
|
||||
dn: cn=john,dc=lukemelia,dc=com
|
||||
cn: john
|
||||
sn: john
|
||||
objectclass: person
|
||||
userPassword: #{encrypted_password}
|
||||
}
|
||||
end
|
||||
ldif_file
|
||||
end
|
||||
|
||||
def run_cmd(cmd)
|
||||
puts cmd if OUTPUT_DEBUG_INFO
|
||||
cmd_out = `#{cmd}`
|
||||
puts cmd_out if OUTPUT_DEBUG_INFO
|
||||
end
|
||||
|
||||
def get_pid_file_path(tempfile)
|
||||
tempfile.path + '.pid'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -2,9 +2,11 @@ ENV["RAILS_ENV"] = "test"
|
|||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
||||
require 'test_help'
|
||||
|
||||
class User < ActiveRecord::Base
|
||||
def self.get_salt
|
||||
"change-me"
|
||||
module Tracks
|
||||
class Config
|
||||
def self.salt
|
||||
"change-me"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -50,7 +52,7 @@ class ActionController::IntegrationTest
|
|||
|
||||
def assert_test_environment_ok
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", User.get_salt()
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
end
|
||||
|
||||
def authenticated_post_xml(url, username, password, parameters, headers = {})
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ class UserTest < Test::Unit::TestCase
|
|||
|
||||
def setup
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", User.get_salt()
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
@admin_user = User.find(1)
|
||||
@other_user = User.find(2)
|
||||
end
|
||||
|
|
@ -16,7 +16,7 @@ class UserTest < Test::Unit::TestCase
|
|||
assert_kind_of User, @admin_user
|
||||
assert_equal 1, @admin_user.id
|
||||
assert_equal "admin", @admin_user.login
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{User.get_salt()}--abracadabra--")}", @admin_user.password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--abracadabra--")}", @admin_user.password
|
||||
assert_not_nil @admin_user.word
|
||||
assert @admin_user.is_admin
|
||||
end
|
||||
|
|
@ -26,7 +26,7 @@ class UserTest < Test::Unit::TestCase
|
|||
assert_kind_of User, @other_user
|
||||
assert_equal 2, @other_user.id
|
||||
assert_equal "jane", @other_user.login
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{User.get_salt()}--sesame--")}", @other_user.password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
|
||||
assert_not_nil @other_user.word
|
||||
assert @other_user.is_admin == false || @other_user.is_admin == 0
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@ class UserTest < Test::Unit::TestCase
|
|||
# Test a password shorter than 5 characters
|
||||
#
|
||||
def test_validate_short_password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{User.get_salt()}--sesame--")}", @other_user.password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
|
||||
@other_user.password = "four"
|
||||
assert !@other_user.save
|
||||
assert_equal 1, @other_user.errors.count
|
||||
|
|
@ -48,7 +48,7 @@ class UserTest < Test::Unit::TestCase
|
|||
# Test a password longer than 40 characters
|
||||
#
|
||||
def test_validate_long_password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{User.get_salt()}--sesame--")}", @other_user.password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
|
||||
@other_user.password = generate_random_string(41)
|
||||
assert !@other_user.save
|
||||
assert_equal 1, @other_user.errors.count
|
||||
|
|
@ -58,7 +58,7 @@ class UserTest < Test::Unit::TestCase
|
|||
# Test that correct length password is valid
|
||||
#
|
||||
def test_validate_correct_length_password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{User.get_salt()}--sesame--")}", @other_user.password
|
||||
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
|
||||
@other_user.password = generate_random_string(6)
|
||||
assert @other_user.save
|
||||
end
|
||||
|
|
|
|||
202
tracks/vendor/plugins/openid_consumer_plugin/LICENSE
vendored
Normal file
202
tracks/vendor/plugins/openid_consumer_plugin/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed 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.
|
||||
22
tracks/vendor/plugins/openid_consumer_plugin/README
vendored
Normal file
22
tracks/vendor/plugins/openid_consumer_plugin/README
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
OpenID Consumer
|
||||
===============
|
||||
|
||||
Enable OpenID authentication and profile exchange from your application.
|
||||
|
||||
PRE-REQUISITES
|
||||
--------------
|
||||
|
||||
* JanRain's Yadis and OpenID 1.2 libraries in Ruby.
|
||||
* These can be obtained using 'gem install ruby-openid'
|
||||
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
To install you need to create a migration and add a controller.
|
||||
|
||||
./script/generate open_id_migration add_open_id_tables
|
||||
./script/generate open_id_consumer_controller open_id
|
||||
|
||||
This can be used well in conjunction with a login system such as ActsAsAuthenticated
|
||||
|
||||
39
tracks/vendor/plugins/openid_consumer_plugin/Rakefile
vendored
Normal file
39
tracks/vendor/plugins/openid_consumer_plugin/Rakefile
vendored
Normal file
|
|
@ -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.
|
||||
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the open_id_consumer plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Generate documentation for the open_id_consumer plugin.'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'OpenIdConsumer'
|
||||
rdoc.options << '--line-numbers' << '--inline-source'
|
||||
rdoc.rdoc_files.include('README')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
|
@ -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.
|
||||
|
||||
class OpenIdConsumerControllerGenerator < Rails::Generator::NamedBase
|
||||
attr_reader :controller_name,
|
||||
:controller_class_path,
|
||||
:controller_file_path,
|
||||
:controller_class_nesting,
|
||||
:controller_class_nesting_depth,
|
||||
:controller_class_name,
|
||||
:controller_singular_name,
|
||||
:controller_plural_name
|
||||
alias_method :controller_file_name, :controller_singular_name
|
||||
alias_method :controller_table_name, :controller_plural_name
|
||||
|
||||
def initialize(runtime_args, runtime_options = {})
|
||||
runtime_args << 'open_id' if runtime_args.empty?
|
||||
super
|
||||
|
||||
# Take controller name from the next argument. Default to the pluralized model name.
|
||||
@controller_name = args.shift
|
||||
@controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name
|
||||
|
||||
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
|
||||
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
|
||||
|
||||
if @controller_class_nesting.empty?
|
||||
@controller_class_name = @controller_class_name_without_nesting
|
||||
else
|
||||
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
||||
end
|
||||
end
|
||||
|
||||
def manifest
|
||||
record do |m|
|
||||
# Check for class naming collisions.
|
||||
m.class_collisions controller_class_path, "#{controller_class_name}Controller",
|
||||
"#{controller_class_name}Helper"
|
||||
|
||||
# Controller, helper, views, and test directories.
|
||||
m.directory File.join('app/controllers', controller_class_path)
|
||||
m.directory File.join('app/helpers', controller_class_path)
|
||||
m.directory File.join('app/views', controller_class_path, controller_file_name)
|
||||
m.directory File.join('test/functional', controller_class_path)
|
||||
|
||||
m.template 'controller.rb',
|
||||
File.join('app/controllers',
|
||||
controller_class_path,
|
||||
"#{controller_file_name}_controller.rb")
|
||||
|
||||
m.template 'functional_test.rb',
|
||||
File.join('test/functional',
|
||||
controller_class_path,
|
||||
"#{controller_file_name}_controller_test.rb")
|
||||
|
||||
m.template 'helper.rb',
|
||||
File.join('app/helpers',
|
||||
controller_class_path,
|
||||
"#{controller_file_name}_helper.rb")
|
||||
|
||||
# Controller templates
|
||||
m.template "index.rhtml",
|
||||
File.join('app/views', controller_class_path, controller_file_name, "index.rhtml")
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
# Override with your own usage banner.
|
||||
def banner
|
||||
"Usage: #{$0} open_id_consumer_controller [open_id]"
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# 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 <%= controller_class_name %>Controller < ApplicationController
|
||||
open_id_consumer :required => [:email, :nickname], :optional => [:fullname, :dob, :gender, :country]
|
||||
|
||||
def index
|
||||
@title = 'Welcome'
|
||||
end
|
||||
|
||||
def begin
|
||||
# If the URL was unusable (either because of network conditions,
|
||||
# a server error, or that the response returned was not an OpenID
|
||||
# identity page), the library will return HTTP_FAILURE or PARSE_ERROR.
|
||||
# Let the user know that the URL is unusable.
|
||||
case open_id_response.status
|
||||
when OpenID::SUCCESS
|
||||
# The URL was a valid identity URL. Now we just need to send a redirect
|
||||
# to the server using the redirect_url the library created for us.
|
||||
|
||||
# redirect to the server
|
||||
redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + '/'), url_for(:action => 'complete'))
|
||||
else
|
||||
flash[:error] = "Unable to find openid server for <q>#{params[:openid_url]}</q>"
|
||||
render :action => :index
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
case open_id_response.status
|
||||
when OpenID::FAILURE
|
||||
# In the case of failure, if info is non-nil, it is the
|
||||
# URL that we were verifying. We include it in the error
|
||||
# message to help the user figure out what happened.
|
||||
if open_id_response.identity_url
|
||||
flash[:message] = "Verification of #{open_id_response.identity_url} failed. "
|
||||
else
|
||||
flash[:message] = "Verification failed. "
|
||||
end
|
||||
flash[:message] += open_id_response.msg.to_s
|
||||
|
||||
when OpenID::SUCCESS
|
||||
# Success means that the transaction completed without
|
||||
# error. If info is nil, it means that the user cancelled
|
||||
# the verification.
|
||||
flash[:message] = "You have successfully verified #{open_id_response.identity_url} as your identity."
|
||||
if open_id_fields.any?
|
||||
flash[:message] << "<hr /> With simple registration fields:<br/>"
|
||||
open_id_fields.each {|k,v| flash[:message] << "<br /><b>#{k}</b>: #{v}"}
|
||||
end
|
||||
|
||||
when OpenID::CANCEL
|
||||
flash[:message] = "Verification cancelled."
|
||||
|
||||
else
|
||||
flash[:message] = "Unknown response status: #{open_id_response.status}"
|
||||
end
|
||||
redirect_to :action => 'index'
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require '<%= controller_file_name %>_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end
|
||||
|
||||
class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = <%= controller_class_name %>Controller.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
|
@ -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 <%= controller_class_name %>Helper
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<% # 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.
|
||||
%>
|
||||
|
||||
<h1><%%= @title %></h1>
|
||||
|
||||
<div><strong><%%= flash[:message] %></strong></div>
|
||||
<div><strong><%%= flash[:error] %></strong></div>
|
||||
|
||||
<p>Please login with your OpenID Identity URL</p>
|
||||
|
||||
<div id="verify-form">
|
||||
<%%= start_form_tag :action => 'begin' %>
|
||||
Identity URL:
|
||||
<input type="text" name="openid_url" style="width: 200px" />
|
||||
<input type="submit" value="Verify" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# 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 OpenIdMigrationGenerator < Rails::Generator::NamedBase
|
||||
def initialize(runtime_args, runtime_options = {})
|
||||
runtime_args << 'add_open_id_tables' if runtime_args.empty?
|
||||
super
|
||||
end
|
||||
|
||||
def manifest
|
||||
record do |m|
|
||||
m.migration_template 'migration.rb', 'db/migrate'
|
||||
end
|
||||
end
|
||||
end
|
||||
45
tracks/vendor/plugins/openid_consumer_plugin/generators/open_id_migration/templates/migration.rb
vendored
Normal file
45
tracks/vendor/plugins/openid_consumer_plugin/generators/open_id_migration/templates/migration.rb
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# 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 <%= class_name %> < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table "open_id_associations", :force => true do |t|
|
||||
t.column "server_url", :binary
|
||||
t.column "handle", :string
|
||||
t.column "secret", :binary
|
||||
t.column "issued", :integer
|
||||
t.column "lifetime", :integer
|
||||
t.column "assoc_type", :string
|
||||
end
|
||||
|
||||
create_table "open_id_nonces", :force => true do |t|
|
||||
t.column "nonce", :string
|
||||
t.column "created", :integer
|
||||
end
|
||||
|
||||
create_table "open_id_settings", :force => true do |t|
|
||||
t.column "setting", :string
|
||||
t.column "value", :binary
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table "open_id_associations"
|
||||
drop_table "open_id_nonces"
|
||||
drop_table "open_id_settings"
|
||||
end
|
||||
end
|
||||
23
tracks/vendor/plugins/openid_consumer_plugin/init.rb
vendored
Normal file
23
tracks/vendor/plugins/openid_consumer_plugin/init.rb
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# 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 << ActionController::Base
|
||||
def open_id_consumer(options = {})
|
||||
include OpenIdConsumer::ControllerMethods
|
||||
self.open_id_consumer_options = options
|
||||
end
|
||||
end
|
||||
18
tracks/vendor/plugins/openid_consumer_plugin/install.rb
vendored
Normal file
18
tracks/vendor/plugins/openid_consumer_plugin/install.rb
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# 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.
|
||||
|
||||
puts IO.read(File.join(File.dirname(__FILE__), 'README'))
|
||||
103
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/active_record_open_id_store.rb
vendored
Normal file
103
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/active_record_open_id_store.rb
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# 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
|
||||
|
||||
module OpenIdConsumer
|
||||
class ActiveRecordOpenIdStore < OpenID::Store
|
||||
def get_auth_key
|
||||
setting = Setting.find_by_setting 'auth_key'
|
||||
if setting.nil?
|
||||
auth_key = OpenID::Util.random_string(20)
|
||||
setting = Setting.create :setting => 'auth_key', :value => auth_key
|
||||
end
|
||||
setting.value
|
||||
end
|
||||
|
||||
def store_association(server_url, assoc)
|
||||
remove_association(server_url, assoc.handle)
|
||||
Association.create(:server_url => server_url,
|
||||
:handle => assoc.handle,
|
||||
:secret => assoc.secret,
|
||||
:issued => assoc.issued,
|
||||
:lifetime => assoc.lifetime,
|
||||
:assoc_type => assoc.assoc_type)
|
||||
end
|
||||
|
||||
def get_association(server_url, handle=nil)
|
||||
assocs = handle.blank? ?
|
||||
Association.find_all_by_server_url(server_url) :
|
||||
Association.find_all_by_server_url_and_handle(server_url, handle)
|
||||
|
||||
assocs.reverse.each do |assoc|
|
||||
a = assoc.from_record
|
||||
if a.expired?
|
||||
assoc.destroy
|
||||
else
|
||||
return a
|
||||
end
|
||||
end if assocs.any?
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def remove_association(server_url, handle)
|
||||
assoc = Association.find_by_server_url_and_handle(server_url, handle)
|
||||
unless assoc.nil?
|
||||
assoc.destroy
|
||||
return true
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def store_nonce(nonce)
|
||||
use_nonce(nonce)
|
||||
Nonce.create :nonce => nonce, :created => Time.now.to_i
|
||||
end
|
||||
|
||||
def use_nonce(nonce)
|
||||
nonce = Nonce.find_by_nonce(nonce)
|
||||
return false if nonce.nil?
|
||||
|
||||
age = Time.now.to_i - nonce.created
|
||||
nonce.destroy
|
||||
|
||||
age < 6.hours # max nonce age of 6 hours
|
||||
end
|
||||
|
||||
def dumb?
|
||||
false
|
||||
end
|
||||
|
||||
# not part of the api, but useful
|
||||
def gc
|
||||
now = Time.now.to_i
|
||||
|
||||
# remove old nonces
|
||||
nonces = Nonce.find(:all)
|
||||
nonces.each {|n| n.destroy if now - n.created > 6.hours} unless nonces.nil?
|
||||
|
||||
# remove expired assocs
|
||||
assocs = Association.find(:all)
|
||||
assocs.each { |a| a.destroy if a.from_record.expired? } unless assocs.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
31
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/association.rb
vendored
Normal file
31
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/association.rb
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# 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
|
||||
|
||||
module OpenIdConsumer
|
||||
class Association < ActiveRecord::Base
|
||||
set_table_name 'open_id_associations'
|
||||
def from_record
|
||||
OpenID::Association.new(handle, secret, issued, lifetime, assoc_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
69
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/controller_methods.rb
vendored
Normal file
69
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/controller_methods.rb
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# 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
|
||||
|
||||
module OpenIdConsumer
|
||||
module ControllerMethods
|
||||
def self.included(controller)
|
||||
controller.class_eval do
|
||||
verify :method => :post, :only => :begin, :params => :openid_url, :redirect_to => { :action => 'index' },
|
||||
:add_flash => { :error => "Enter an Identity URL to verify." }
|
||||
verify :method => :get, :only => :complete, :redirect_to => { :action => 'index' }
|
||||
before_filter :begin_open_id_auth, :only => :begin
|
||||
before_filter :complete_open_id_auth, :only => :complete
|
||||
attr_reader :open_id_response
|
||||
attr_reader :open_id_fields
|
||||
cattr_accessor :open_id_consumer_options
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def open_id_consumer
|
||||
@open_id_consumer ||= OpenID::Consumer.new(
|
||||
session[:openid_session] ||= {},
|
||||
ActiveRecordOpenIdStore.new)
|
||||
end
|
||||
|
||||
def begin_open_id_auth
|
||||
@open_id_response = open_id_consumer.begin(params[:openid_url])
|
||||
add_sreg_params!(@open_id_response) if @open_id_response.status == OpenID::SUCCESS
|
||||
end
|
||||
|
||||
def complete_open_id_auth
|
||||
@open_id_response = open_id_consumer.complete(params)
|
||||
return unless open_id_response.status == OpenID::SUCCESS
|
||||
|
||||
@open_id_fields = open_id_response.extension_response('sreg')
|
||||
logger.debug "***************** sreg params ***************"
|
||||
logger.debug @open_id_fields.inspect
|
||||
logger.debug "***************** sreg params ***************"
|
||||
end
|
||||
|
||||
def add_sreg_params!(openid_response)
|
||||
open_id_consumer_options.keys.inject({}) do |params, key|
|
||||
value = open_id_consumer_options[key]
|
||||
value = value.collect { |v| v.to_s.strip } * ',' if value.respond_to?(:collect)
|
||||
openid_response.add_extension_arg('sreg', key.to_s, value.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/nonce.rb
vendored
Normal file
22
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/nonce.rb
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# 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 OpenIdConsumer
|
||||
class Nonce < ActiveRecord::Base
|
||||
set_table_name 'open_id_nonces'
|
||||
end
|
||||
end
|
||||
22
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/setting.rb
vendored
Normal file
22
tracks/vendor/plugins/openid_consumer_plugin/lib/open_id_consumer/setting.rb
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# 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 OpenIdConsumer
|
||||
class Setting < ActiveRecord::Base
|
||||
set_table_name 'open_id_settings'
|
||||
end
|
||||
end
|
||||
5
tracks/vendor/plugins/simple_ldap_authenticator/README
vendored
Normal file
5
tracks/vendor/plugins/simple_ldap_authenticator/README
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
SimpleLdapAuthenticator
|
||||
=======================
|
||||
|
||||
Allows for simple authentication to an LDAP server with a minimum of
|
||||
configuration. See the RDoc for details.
|
||||
22
tracks/vendor/plugins/simple_ldap_authenticator/Rakefile
vendored
Normal file
22
tracks/vendor/plugins/simple_ldap_authenticator/Rakefile
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the simple_ldap_authenticator plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
desc 'Generate documentation for the simple_ldap_authenticator plugin.'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'SimpleLdapAuthenticator'
|
||||
rdoc.options << '--line-numbers' << '--inline-source'
|
||||
rdoc.rdoc_files.include('README')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
2
tracks/vendor/plugins/simple_ldap_authenticator/init.rb
vendored
Normal file
2
tracks/vendor/plugins/simple_ldap_authenticator/init.rb
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Include hook code here
|
||||
#require 'simple_ldap_authenticator'
|
||||
1
tracks/vendor/plugins/simple_ldap_authenticator/install.rb
vendored
Normal file
1
tracks/vendor/plugins/simple_ldap_authenticator/install.rb
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Install hook code here
|
||||
127
tracks/vendor/plugins/simple_ldap_authenticator/lib/simple_ldap_authenticator.rb
vendored
Normal file
127
tracks/vendor/plugins/simple_ldap_authenticator/lib/simple_ldap_authenticator.rb
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# SimpleLdapAuthenticator
|
||||
#
|
||||
# This plugin supports both Ruby/LDAP and Net::LDAP, defaulting to Ruby/LDAP
|
||||
# if it is available. If both are installed and you want to force the use of
|
||||
# Net::LDAP, set SimpleLdapAuthenticator.ldap_library = 'net/ldap'.
|
||||
|
||||
# Allows for easily authenticating users via LDAP (or LDAPS). If authenticating
|
||||
# via LDAP to a server running on localhost, you should only have to configure
|
||||
# the login_format.
|
||||
#
|
||||
# Can be configured using the following accessors (with examples):
|
||||
# * login_format = '%s@domain.com' # Active Directory, OR
|
||||
# * login_format = 'cn=%s,cn=users,o=organization,c=us' # Other LDAP servers
|
||||
# * servers = ['dc1.domain.com', 'dc2.domain.com'] # names/addresses of LDAP servers to use
|
||||
# * use_ssl = true # for logging in via LDAPS
|
||||
# * port = 3289 # instead of 389 for LDAP or 636 for LDAPS
|
||||
# * logger = RAILS_DEFAULT_LOGGER # for logging authentication successes/failures
|
||||
#
|
||||
# The class is used as a global variable, you are not supposed to create an
|
||||
# instance of it. For example:
|
||||
#
|
||||
# require 'simple_ldap_authenticator'
|
||||
# SimpleLdapAuthenticator.servers = %w'dc1.domain.com dc2.domain.com'
|
||||
# SimpleLdapAuthenticator.use_ssl = true
|
||||
# SimpleLdapAuthenticator.login_format = '%s@domain.com'
|
||||
# SimpleLdapAuthenticator.logger = RAILS_DEFAULT_LOGGER
|
||||
# class LoginController < ApplicationController
|
||||
# def login
|
||||
# return redirect_to(:action=>'try_again') unless SimpleLdapAuthenticator.valid?(params[:username], params[:password])
|
||||
# session[:username] = params[:username]
|
||||
# end
|
||||
# end
|
||||
class SimpleLdapAuthenticator
|
||||
class << self
|
||||
@servers = ['127.0.0.1']
|
||||
@use_ssl = false
|
||||
@login_format = '%s'
|
||||
attr_accessor :servers, :use_ssl, :port, :login_format, :logger, :connection, :ldap_library
|
||||
|
||||
# Load the required LDAP library, either 'ldap' or 'net/ldap'
|
||||
def load_ldap_library
|
||||
return if @ldap_library_loaded
|
||||
if ldap_library
|
||||
if ldap_library == 'net/ldap'
|
||||
require 'net/ldap'
|
||||
else
|
||||
require 'ldap'
|
||||
require 'ldap/control'
|
||||
end
|
||||
else
|
||||
begin
|
||||
require 'ldap'
|
||||
require 'ldap/control'
|
||||
ldap_library = 'ldap'
|
||||
rescue LoadError
|
||||
require 'net/ldap'
|
||||
ldap_library = 'net/ldap'
|
||||
end
|
||||
end
|
||||
@ldap_library_loaded = true
|
||||
end
|
||||
|
||||
# The next LDAP server to which to connect
|
||||
def server
|
||||
servers[0]
|
||||
end
|
||||
|
||||
# The connection to the LDAP server. A single connection is made and the
|
||||
# connection is only changed if a server returns an error other than
|
||||
# invalid password.
|
||||
def connection
|
||||
return @connection if @connection
|
||||
load_ldap_library
|
||||
@connection = if ldap_library == 'net/ldap'
|
||||
Net::LDAP.new(:host=>server, :port=>(port), :encryption=>(:simple_tls if use_ssl))
|
||||
else
|
||||
(use_ssl ? LDAP::SSLConn : LDAP::Conn).new(server, port)
|
||||
end
|
||||
end
|
||||
|
||||
# The port to use. Defaults to 389 for LDAP and 636 for LDAPS.
|
||||
def port
|
||||
@port ||= use_ssl ? 636 : 389
|
||||
end
|
||||
|
||||
# Disconnect from current LDAP server and use a different LDAP server on the
|
||||
# next authentication attempt
|
||||
def switch_server
|
||||
self.connection = nil
|
||||
servers << servers.shift
|
||||
end
|
||||
|
||||
# Check the validity of a login/password combination
|
||||
def valid?(login, password)
|
||||
if ldap_library == 'net/ldap'
|
||||
connection.authenticate(login_format % login.to_s, password.to_s)
|
||||
begin
|
||||
if connection.bind
|
||||
logger.info("Authenticated #{login.to_s} by #{server}") if logger
|
||||
true
|
||||
else
|
||||
logger.info("Error attempting to authenticate #{login.to_s} by #{server}: #{connection.get_operation_result.code} #{connection.get_operation_result.message}") if logger
|
||||
switch_server unless connection.get_operation_result.code == 49
|
||||
false
|
||||
end
|
||||
rescue Net::LDAP::LdapError => error
|
||||
logger.info("Error attempting to authenticate #{login.to_s} by #{server}: #{error.message}") if logger
|
||||
switch_server
|
||||
false
|
||||
end
|
||||
else
|
||||
connection.unbind if connection.bound?
|
||||
begin
|
||||
connection.bind(login_format % login.to_s, password.to_s)
|
||||
connection.unbind
|
||||
logger.info("Authenticated #{login.to_s} by #{server}") if logger
|
||||
true
|
||||
rescue LDAP::ResultError => error
|
||||
connection.unbind if connection.bound?
|
||||
logger.info("Error attempting to authenticate #{login.to_s} by #{server}: #{error.message}") if logger
|
||||
switch_server unless error.message == 'Invalid credentials'
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
4
tracks/vendor/plugins/simple_ldap_authenticator/tasks/simple_ldap_authenticator_tasks.rake
vendored
Normal file
4
tracks/vendor/plugins/simple_ldap_authenticator/tasks/simple_ldap_authenticator_tasks.rake
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# desc "Explaining what the task does"
|
||||
# task :simple_ldap_authenticator do
|
||||
# # Task goes here
|
||||
# end
|
||||
8
tracks/vendor/plugins/simple_ldap_authenticator/test/simple_ldap_authenticator_test.rb
vendored
Normal file
8
tracks/vendor/plugins/simple_ldap_authenticator/test/simple_ldap_authenticator_test.rb
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
require 'test/unit'
|
||||
|
||||
class SimpleLdapAuthenticatorTest < Test::Unit::TestCase
|
||||
# Replace this with your real tests.
|
||||
def test_this_plugin
|
||||
flunk
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue