adva_user 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README +114 -0
  6. data/README.md +29 -0
  7. data/Rakefile +2 -0
  8. data/adva_user.gemspec +17 -0
  9. data/app/controllers/admin/base_account_controller.rb +13 -0
  10. data/app/controllers/admin/users_controller.rb +95 -0
  11. data/app/controllers/password_controller.rb +36 -0
  12. data/app/controllers/session_controller.rb +30 -0
  13. data/app/helpers/users_helper.rb +27 -0
  14. data/app/models/account.rb +7 -0
  15. data/app/models/membership.rb +16 -0
  16. data/app/models/password_mailer.rb +43 -0
  17. data/app/models/user.rb +106 -0
  18. data/app/views/admin/users/_form.html.erb +29 -0
  19. data/app/views/admin/users/_sidebar.html.erb +8 -0
  20. data/app/views/admin/users/edit.html.erb +7 -0
  21. data/app/views/admin/users/index.html.erb +13 -0
  22. data/app/views/admin/users/new.html.erb +5 -0
  23. data/app/views/admin/users/show.html.erb +27 -0
  24. data/app/views/layouts/login.html.erb +24 -0
  25. data/app/views/password/edit.html.erb +14 -0
  26. data/app/views/password/new.html.erb +13 -0
  27. data/app/views/password_mailer/reset_password_email.html.erb +3 -0
  28. data/app/views/password_mailer/updated_password_email.html.erb +1 -0
  29. data/app/views/session/new.html.erb +17 -0
  30. data/config/initializers/menus.rb +25 -0
  31. data/config/routes.rb +14 -0
  32. data/db/migrate/20080402000001_create_users_table.rb +33 -0
  33. data/db/migrate/20080402000005_create_memberships_table.rb +13 -0
  34. data/db/migrate/20090625124502_create_accounts.rb +13 -0
  35. data/db/migrate/20090625133231_add_account_to_user.rb +10 -0
  36. data/lib/action_controller/authenticate_anonymous.rb +70 -0
  37. data/lib/action_controller/authenticate_user.rb +201 -0
  38. data/lib/active_record/belongs_to_author.rb +37 -0
  39. data/lib/adva_user.rb +28 -0
  40. data/lib/adva_user/version.rb +3 -0
  41. data/lib/login/helper_integration.rb +11 -0
  42. data/lib/login/mail_config.rb +39 -0
  43. data/test/contexts.rb +42 -0
  44. data/test/fixtures.rb +18 -0
  45. data/test/functional/admin/users_controller_test.rb +176 -0
  46. data/test/functional/password_controller_test.rb +96 -0
  47. data/test/functional/session_controller_test.rb +1 -0
  48. data/test/functional/user_controller_test.rb +95 -0
  49. data/test/integration/anonymous_login_test.rb +39 -0
  50. data/test/integration/edit_user_test.rb +44 -0
  51. data/test/integration/memberships_test.rb +52 -0
  52. data/test/integration/user_deletion_test.rb +27 -0
  53. data/test/integration/user_login_test.rb +53 -0
  54. data/test/integration/user_login_with_remember_me_test.rb +20 -0
  55. data/test/integration/user_registration_test.rb +64 -0
  56. data/test/test_helper.rb +1 -0
  57. data/test/unit/cells/user_cell_test.rb +13 -0
  58. data/test/unit/helpers/users_helper_test.rb +52 -0
  59. data/test/unit/models/account_test.rb +21 -0
  60. data/test/unit/models/anonymous_test.rb +54 -0
  61. data/test/unit/models/password_mailer_test.rb +26 -0
  62. data/test/unit/models/user_mailer_test.rb +16 -0
  63. data/test/unit/models/user_test.rb +173 -0
  64. data/vendor/gems/authentication/.gitignore +17 -0
  65. data/vendor/gems/authentication/Gemfile +4 -0
  66. data/vendor/gems/authentication/LICENSE +22 -0
  67. data/vendor/gems/authentication/MIT-LICENSE +38 -0
  68. data/vendor/gems/authentication/README +39 -0
  69. data/vendor/gems/authentication/README.md +29 -0
  70. data/vendor/gems/authentication/RUNNING_UNIT_TESTS +13 -0
  71. data/vendor/gems/authentication/Rakefile +61 -0
  72. data/vendor/gems/authentication/authentication.gemspec +17 -0
  73. data/vendor/gems/authentication/lib/authentication.rb +270 -0
  74. data/vendor/gems/authentication/lib/authentication/active_record_extensions.rb +11 -0
  75. data/vendor/gems/authentication/lib/authentication/bogus.rb +13 -0
  76. data/vendor/gems/authentication/lib/authentication/hash_helper.rb +26 -0
  77. data/vendor/gems/authentication/lib/authentication/ldap.rb +49 -0
  78. data/vendor/gems/authentication/lib/authentication/remember_me.rb +52 -0
  79. data/vendor/gems/authentication/lib/authentication/salted_hash.rb +53 -0
  80. data/vendor/gems/authentication/lib/authentication/single_token.rb +53 -0
  81. data/vendor/gems/authentication/lib/authentication/version.rb +3 -0
  82. data/vendor/gems/authentication/lib/radius/dictionary +207 -0
  83. data/vendor/gems/authentication/test_backup/abstract_unit.rb +30 -0
  84. data/vendor/gems/authentication/test_backup/active_record_extension_test.rb +17 -0
  85. data/vendor/gems/authentication/test_backup/authentication_test.rb +231 -0
  86. data/vendor/gems/authentication/test_backup/database.yml +12 -0
  87. data/vendor/gems/authentication/test_backup/fixtures/user.rb +3 -0
  88. data/vendor/gems/authentication/test_backup/fixtures/users.yml +3 -0
  89. data/vendor/gems/authentication/test_backup/options_test.rb +100 -0
  90. data/vendor/gems/authentication/test_backup/remember_me_test.rb +41 -0
  91. data/vendor/gems/authentication/test_backup/salted_hash_test.rb +38 -0
  92. data/vendor/gems/authentication/test_backup/schema.rb +10 -0
  93. data/vendor/gems/authentication/test_backup/single_token_test.rb +44 -0
  94. data/vendor/gems/authentication/test_backup/test_helper.rb +8 -0
  95. metadata +157 -0
@@ -0,0 +1,43 @@
1
+ require "login/mail_config"
2
+
3
+ class PasswordMailer < ActionMailer::Base
4
+ include Login::MailConfig
5
+
6
+ class << self
7
+ def handle_user_password_reset_requested!(event)
8
+ deliver_reset_password_email(
9
+ :user => event.object,
10
+ :from => site(event.source.site).email_from,
11
+ :reset_link => password_reset_link(event.source, event.token),
12
+ :token => event.token
13
+ )
14
+ end
15
+
16
+ def handle_user_password_updated!(event)
17
+ deliver_updated_password_email(
18
+ :user => event.object,
19
+ :from => site(event.source.site).email_from
20
+ )
21
+ end
22
+
23
+ private
24
+
25
+ def password_reset_link(controller, token)
26
+ controller.send(:url_for, :action => 'edit', :token => token)
27
+ end
28
+ end
29
+
30
+ def reset_password_email(attributes = {})
31
+ recipients attributes[:user].email
32
+ from attributes[:from]
33
+ subject I18n.t(:'adva.passwords.notifications.reset_password.subject')
34
+ body attributes
35
+ end
36
+
37
+ def updated_password_email(attributes = {})
38
+ recipients attributes[:user].email
39
+ from attributes[:from]
40
+ subject I18n.t(:'adva.passwords.notifications.password_updated.subject')
41
+ body attributes
42
+ end
43
+ end
@@ -0,0 +1,106 @@
1
+ class User < ActiveRecord::Base
2
+ acts_as_authenticated_user
3
+
4
+ # TODO how do we work this in?
5
+ # acts_as_authenticated_user :token_with => 'Authentication::SingleToken',
6
+ # :authenticate_with => nil
7
+
8
+ scope :verified, -> { where.not(verified_at: nil) }
9
+
10
+ belongs_to :account
11
+ has_many :sites, :through => :memberships
12
+ has_many :memberships, :dependent => :delete_all
13
+
14
+ validates_presence_of :first_name, :email
15
+ validates_uniqueness_of :email # i.e. account attributes are unique per application, not per site
16
+ validates_length_of :first_name, :within => 1..40
17
+ validates_length_of :last_name, :allow_nil => true, :within => 0..40
18
+ validates_format_of :email, :allow_nil => true,
19
+ :with => /(\A(\s*)\Z)|(\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z)/i
20
+
21
+ validates_presence_of :password, :if => :password_required?
22
+ validates_length_of :password, :within => 4..40, :if => :password_required?
23
+
24
+ class << self
25
+ def authenticate(credentials)
26
+ return false unless user = User.find_by_email(credentials[:email])
27
+ user.authenticate(credentials[:password]) ? user : false
28
+ end
29
+
30
+ def anonymous(attributes = {}) # FIXME rename to build_anonymous
31
+ attributes[:anonymous] = true
32
+ new attributes
33
+ end
34
+ end
35
+
36
+ def attributes=(attributes)
37
+ attributes.symbolize_keys!
38
+ memberships = attributes.delete :memberships
39
+ super.tap do
40
+ update_memberships memberships if memberships
41
+ end
42
+ end
43
+
44
+ def update_memberships(memberships)
45
+ memberships.each do |site_id, active|
46
+ site = Site.find(site_id)
47
+ if active
48
+ self.sites << site unless member_of?(site)
49
+ else
50
+ self.sites.delete(site) if member_of?(site)
51
+ end
52
+ end
53
+ end
54
+
55
+ def member_of?(site)
56
+ sites.include?(site)
57
+ end
58
+
59
+ def verified?
60
+ !verified_at.nil?
61
+ end
62
+
63
+ def verify!
64
+ update_attributes :verified_at => Time.zone.now if verified_at.nil?
65
+ end
66
+
67
+ # def restore!
68
+ # update_attributes :deleted_at => nil if deleted_at
69
+ # end
70
+
71
+ def registered?
72
+ !new_record? && !anonymous?
73
+ end
74
+
75
+ def name=(name)
76
+ self.first_name = name
77
+ end
78
+
79
+ def name
80
+ last_name ? "#{first_name} #{last_name}" : first_name
81
+ end
82
+
83
+ def to_s
84
+ name
85
+ end
86
+
87
+ def email_with_name
88
+ "#{name} <#{email}>"
89
+ end
90
+
91
+ def homepage
92
+ return nil unless self[:homepage]
93
+
94
+ self[:homepage][0..6] == 'http://' ? self[:homepage] : 'http://' + self[:homepage]
95
+ end
96
+
97
+ def first_name_from_email
98
+ self.first_name.blank? && self.email ? self.email.split('@').first : self.first_name
99
+ end
100
+
101
+ protected
102
+
103
+ def password_required?
104
+ !anonymous? && (password_hash.nil? || password.present?)
105
+ end
106
+ end
@@ -0,0 +1,29 @@
1
+ <fieldset>
2
+ <div class="col">
3
+ <%= f.text_field :first_name, :label => "First name" %>
4
+ <%= f.text_field :email, :label => "Email" %>
5
+ <%= f.password_field :password, :label => "Password" %>
6
+ </div>
7
+
8
+ <div class="col">
9
+ <%= f.text_field :last_name, :label => "Last name" %>
10
+ <%= f.text_field :homepage, :label => "Homepage" %>
11
+ </div>
12
+ </fieldset>
13
+
14
+ <h4><%= t(:'adva.titles.roles') %></h4>
15
+ <p class="hint text_only"><%= t(:'adva.hints.roles') %></p>
16
+
17
+ <fieldset>
18
+ <% if current_user.has_role?(:superuser) %>
19
+ <p>
20
+ <%= hidden_field_tag "user[roles_attributes][0][selected]", 0 %>
21
+ <span class='hint'><%= t(:'adva.roles.hints.superuser') %></span>
22
+ <%= check_box_tag "user[roles_attributes][0][selected]", 1, @user.has_global_role?(:superuser), :id => "user_role_superuser" %>
23
+ <%= hidden_field_tag "user[roles_attributes][0][name]", 'superuser' %>
24
+ <%= f.label "role_superuser", t(:'adva.roles.labels.superuser'), :class => 'light inline' %>
25
+ </p>
26
+ <% end %>
27
+ </fieldset>
28
+
29
+ <% save_or_cancel_links(f, :cancel_url => admin_site_users_path(@site)) %>
@@ -0,0 +1,8 @@
1
+ <% content_for :sidebar do %>
2
+ <div class="tabs">
3
+ <div class="tab active">
4
+ <%= gravatar_img(@user) %>
5
+ </div>
6
+ </div>
7
+ <% end -%>
8
+
@@ -0,0 +1,7 @@
1
+ <h2><%= t(:'adva.users.titles.edit') %></h2>
2
+
3
+ <%= form_for [:admin, @site, @user] do |f| -%>
4
+ <%= render :partial => 'form', :locals => {:f => f} %>
5
+ <% end -%>
6
+
7
+ <%= render :partial => 'sidebar' %>
@@ -0,0 +1,13 @@
1
+ <ul id="users">
2
+ <% @users.each do |user| %>
3
+ <li>
4
+ <%= gravatar_img(user) %>
5
+ <h4><%= link_to user.name, [:admin, @site, user] %></h4>
6
+ <p><%= user.email %></p>
7
+ <p class="actions">
8
+ <%= link_to t(:'adva.links.edit'), [:edit, :admin, @site, user], :class => 'edit' %>
9
+ <%= link_to t(:'adva.links.delete'), [:admin, @site, user], :class => 'delete', :data => { :confirm => t(:'adva.users.confirm_delete') }, :method => :delete %>
10
+ </p>
11
+ </li>
12
+ <% end %>
13
+ </ul>
@@ -0,0 +1,5 @@
1
+ <h2><%= t(:'adva.users.titles.new') %></h2>
2
+
3
+ <%= form_for [:admin, @site, @user] do |f| -%>
4
+ <%= render :partial => 'form', :locals => {:f => f} %>
5
+ <% end -%>
@@ -0,0 +1,27 @@
1
+ <h2><%= @user.name %></h2>
2
+
3
+ <h3><%= t(:'adva.common.details') %></h3>
4
+ <p>
5
+ <%= t(:'adva.users.labels.email') %>:
6
+ <%= @user.email %>
7
+ </p>
8
+
9
+ <% if @user.homepage %>
10
+ <p>
11
+ <%= t(:'adva.users.labels.url') %>:
12
+ <%= link_to @user.homepage, @user.homepage %>
13
+ </p>
14
+ <% end %>
15
+
16
+ <h3><%= t(:'adva.common.events') %></h3>
17
+ <p>
18
+ <%= t(:'adva.users.labels.created_at') %>:
19
+ <%= @user.created_at %>
20
+ </p>
21
+
22
+ <p>
23
+ <%= t(:'adva.users.labels.updated_at') %>:
24
+ <%= @user.updated_at %>
25
+ </p>
26
+
27
+ <%= render :partial => 'sidebar' %>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
5
+ <meta name="generator" content="adva-cms - Open source content management platform" />
6
+ <title>adva-cms: <%= controller.controller_name %></title>
7
+
8
+ <%= stylesheet_link_tag "adva_cms/admin" %>
9
+ <%= javascript_include_tag "adva_cms/application" %>
10
+ <%= yield :head %>
11
+ </head>
12
+ <body>
13
+ <div id="header">
14
+ </div>
15
+
16
+ <div class="main">
17
+ <div id="flashes"><%= render :partial => 'shared/flash' %></div>
18
+ <div id="content">
19
+ <%= yield %>
20
+ </div>
21
+ </div>
22
+
23
+ </body>
24
+ </html>
@@ -0,0 +1,14 @@
1
+ <h2><%= t(:'adva.passwords.titles.edit') %></h2>
2
+
3
+ <p><%= params[:token].blank? ? t(:'adva.passwords.info.please_enter_new_password_and_token') : t(:'adva.passwords.info.please_enter_new_password') %></p>
4
+
5
+ <%= form_for 'user', :url => password_path, :html => { :method => :put } do |f| %>
6
+ <% f.field_set do %>
7
+ <%= label_tag(t(:'adva.passwords.attributes.token')) + text_field_tag('token') unless current_user %>
8
+ <%= f.password_field :password, :label => :"adva.users.attributes.new_password" %>
9
+ <% end %>
10
+
11
+ <% f.buttons do %>
12
+ <%= submit_tag t(:'adva.common.save') %>
13
+ <% end %>
14
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <h2><%= t(:'adva.passwords.titles.new') %></h2>
2
+
3
+ <%= form_tag password_path do %>
4
+ <fieldset>
5
+ <p><%= t(:'adva.passwords.info.please_enter_email_to_reset_password') %></p>
6
+ <%= label_tag 'user[email]', t(:"adva.users.attributes.email") %>
7
+ <%= text_field_tag 'user[email]' %>
8
+ </fieldset>
9
+
10
+ <% buttons do %>
11
+ <%= submit_tag t(:'adva.passwords.links.reset') %>
12
+ <% end %>
13
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= t(:'adva.passwords.notifications.reset_password.body', :name => @user.name, :link => @reset_link, :token => @token) %>
2
+
3
+
@@ -0,0 +1 @@
1
+ <%= t(:'adva.passwords.notifications.password_updated.body', :name => @user.name) %>
@@ -0,0 +1,17 @@
1
+ <div id="centered_box">
2
+ <%= form_for @user, :url => session_path, :html => {:id => 'login'} do |f| %>
3
+ <%= hidden_field_tag :return_to, params[:return_to] if params[:return_to] %>
4
+
5
+ <fieldset>
6
+ <%= f.text_field :email, :class => 'big', :label => "Email" %>
7
+ <%= f.password_field :password, :class => 'big', :label => "Password" %>
8
+ <%= check_box_tag 'user[remember_me]', 1, @remember_me, :id => 'user_remember_me' %>
9
+ <%= label_tag :user_remember_me, t(:'adva.session.labels.remember_me'), :class => 'inline light' %>
10
+ </fieldset>
11
+
12
+ <fieldset>
13
+ <%= submit_tag "Login", :id => 'commit' %> <%= t(:'adva.common.connector.or')%>
14
+ <%= link_to t(:'adva.passwords.titles.new'), new_password_path %>
15
+ </fieldset>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,25 @@
1
+ module Menus
2
+ module Admin
3
+ class Users < Menu::Group
4
+ define do
5
+ id :main
6
+ parent Sites.new.build(scope).find(:users)
7
+
8
+ menu :left, :class => 'left' do
9
+ item :users, :action => :index, :resource => [@site, :user]
10
+ end
11
+ menu :actions, :class => 'actions' do
12
+ activates object.parent.find(:users)
13
+ item :new, :action => :new, :resource => [@site, :user]
14
+ if @user && !@user.new_record?
15
+ item :show, :url => admin_site_user_path(@site, @user)
16
+ item :edit, :url => edit_admin_site_user_path(@site, @user)
17
+ # item :show, :action => :show, :resource => @user
18
+ # item :edit, :action => :edit, :resource => @user
19
+ item :delete, :content => link_to("Delete", [:admin, @site, @user], :method => :delete)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ Rails.application.routes.draw do
2
+ get "login" => "session#new"
3
+ delete "logout" => "session#destroy"
4
+
5
+ resource :session, :controller => "session"
6
+ resource :password, :controller => "password"
7
+
8
+ namespace :admin do
9
+ resources :users
10
+ resources :sites do
11
+ resources :users
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ class CreateUsersTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :first_name, :limit => 40
5
+ t.string :last_name, :limit => 40
6
+ t.string :email, :limit => 100
7
+ t.string :homepage
8
+ t.string :about
9
+ t.string :signature
10
+
11
+ t.string :password_hash, :limit => 40
12
+ t.string :password_salt, :limit => 40
13
+
14
+ t.string :ip
15
+ t.string :agent
16
+ t.string :referer
17
+
18
+ t.string :remember_me, :limit => 40
19
+ t.string :token_key, :limit => 40
20
+ t.datetime :token_expiration
21
+
22
+ t.boolean :anonymous, :default => false
23
+
24
+ t.timestamps
25
+ t.datetime :verified_at
26
+ t.datetime :deleted_at
27
+ end
28
+ end
29
+
30
+ def self.down
31
+ drop_table :users
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ class CreateMembershipsTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :memberships, :force => true do |t|
4
+ t.references :site
5
+ t.references :user
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :memberships
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateAccounts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :accounts do |t|
4
+ t.string :name
5
+
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :accounts
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class AddAccountToUser < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :account_id, :integer
4
+ add_index :users, :account_id
5
+ end
6
+
7
+ def self.down
8
+ remove_column :users, :account_id
9
+ end
10
+ end