alchemy-devise 1.1.0

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 (42) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +39 -0
  3. data/app/assets/stylesheets/alchemy/custom.scss +2 -0
  4. data/app/assets/stylesheets/alchemy/login.scss +55 -0
  5. data/app/assets/stylesheets/alchemy/users.scss +44 -0
  6. data/app/controllers/alchemy/admin/users_controller.rb +81 -0
  7. data/app/controllers/alchemy/base_controller_extension.rb +12 -0
  8. data/app/controllers/alchemy/passwords_controller.rb +31 -0
  9. data/app/controllers/alchemy/user_sessions_controller.rb +68 -0
  10. data/app/controllers/alchemy/users_controller.rb +46 -0
  11. data/app/mailers/alchemy/notifications.rb +33 -0
  12. data/app/models/alchemy/user.rb +178 -0
  13. data/app/views/alchemy/admin/users/_table.html.erb +69 -0
  14. data/app/views/alchemy/admin/users/_user.html.erb +39 -0
  15. data/app/views/alchemy/admin/users/edit.html.erb +6 -0
  16. data/app/views/alchemy/admin/users/index.html.erb +58 -0
  17. data/app/views/alchemy/admin/users/new.html.erb +6 -0
  18. data/app/views/alchemy/notifications/alchemy_user_created.de.text.erb +15 -0
  19. data/app/views/alchemy/notifications/alchemy_user_created.en.text.erb +15 -0
  20. data/app/views/alchemy/notifications/registered_user_created.de.text.erb +13 -0
  21. data/app/views/alchemy/notifications/registered_user_created.en.text.erb +13 -0
  22. data/app/views/alchemy/notifications/reset_password_instructions.de.text.erb +8 -0
  23. data/app/views/alchemy/notifications/reset_password_instructions.en.text.erb +8 -0
  24. data/app/views/alchemy/passwords/edit.html.erb +35 -0
  25. data/app/views/alchemy/passwords/new.html.erb +30 -0
  26. data/app/views/alchemy/user_sessions/new.html.erb +48 -0
  27. data/app/views/alchemy/users/new.html.erb +14 -0
  28. data/config/authorization_rules.rb +30 -0
  29. data/config/initializers/alchemy.rb +19 -0
  30. data/config/initializers/devise.rb +242 -0
  31. data/config/locales/alchemy.de.yml +44 -0
  32. data/config/locales/alchemy.en.yml +41 -0
  33. data/config/locales/devise.de.yml +58 -0
  34. data/config/locales/devise.en.yml +60 -0
  35. data/config/routes.rb +26 -0
  36. data/config/spring.rb +1 -0
  37. data/db/migrate/20131015124700_create_alchemy_users.rb +33 -0
  38. data/db/migrate/20131225232042_add_alchemy_roles_to_alchemy_users.rb +19 -0
  39. data/lib/alchemy/devise.rb +6 -0
  40. data/lib/alchemy/devise/engine.rb +20 -0
  41. data/lib/alchemy/devise/version.rb +5 -0
  42. metadata +153 -0
@@ -0,0 +1,69 @@
1
+ <table>
2
+ <tr>
3
+ <td class="label"><%= f.label 'gender' %></td>
4
+ <td class="select"><%= f.select 'gender', options_for_select(@user_genders, @user.gender), {:prompt => _t('Please choose')}, :class => 'alchemy_selectbox long', :autofocus => true -%></td>
5
+ </tr>
6
+ <tr>
7
+ <td class="label"><%= f.label 'firstname' %></td>
8
+ <td class="input"><%= f.text_field 'firstname', :class => 'thin_border long' %></td>
9
+ </tr>
10
+ <tr>
11
+ <td class="label"><%= f.label 'lastname' %></td>
12
+ <td class="input"><%= f.text_field 'lastname', :class => 'thin_border long' %></td>
13
+ </tr>
14
+ <tr>
15
+ <td class="label mandatory"><%= f.label 'login' %></td>
16
+ <td class="input"><%= f.text_field 'login', :class => 'thin_border long', :required => true, :autofocus => true %></td>
17
+ </tr>
18
+ <tr>
19
+ <td class="label mandatory"><%= f.label 'email' %></td>
20
+ <td class="input"><%= f.email_field 'email', :class => 'thin_border long', :required => true %></td>
21
+ </tr>
22
+ <tr>
23
+ <td class="label"><%= f.label 'language' %></td>
24
+ <td class="select"><%= f.select 'language', translations_for_select, {}, {:class => 'alchemy_selectbox long'} %></td>
25
+ </tr>
26
+ <tr>
27
+ <td class="label mandatory"><%= f.label 'password' %></td>
28
+ <td class="input mandatory"><%= f.password_field 'password', :class => 'thin_border long', :autocomplete => "off", :required => action_name == 'signup' %></td>
29
+ </tr>
30
+ <tr>
31
+ <td class="label mandatory"><%= f.label 'password_confirmation' %></td>
32
+ <td class="input"><%= f.password_field 'password_confirmation', :class => 'thin_border long', :autocomplete => "off", :required => action_name == 'signup' %></td>
33
+ </tr>
34
+ <% if @signup %>
35
+ <%= f.hidden_field :alchemy_roles %>
36
+ <% elsif permitted_to? :update_roles %>
37
+ <tr>
38
+ <td class="label"><%= f.label 'alchemy_roles' %></td>
39
+ <td id="user_roles">
40
+ <% Alchemy::User::ROLES.each do |role| %>
41
+ <label>
42
+ <%= check_box_tag 'user[alchemy_roles][]', role, @user.has_role?(role) %>
43
+ <%= Alchemy::User.human_rolename(role) %>
44
+ </label>
45
+ <% end %>
46
+ </td>
47
+ </tr>
48
+ <% end %>
49
+ <% unless @signup %>
50
+ <tr>
51
+ <td class="label"><%= f.label :tag_list %></td>
52
+ <td class="input">
53
+ <%= render 'alchemy/admin/partials/autocomplete_tag_list', :f => f, :object => @user %>
54
+ </td>
55
+ </tr>
56
+ <% end %>
57
+ <tr>
58
+ <td>&nbsp;</td>
59
+ <td class="checkbox long">
60
+ <%= f.check_box(:send_credentials, checked: @user.new_record?) %>
61
+ <%= f.label(:send_credentials) %>
62
+ </td>
63
+ </tr>
64
+ <tr>
65
+ <td class="submit" colspan="2">
66
+ <%= f.button _t(:save), :class => 'button' %>
67
+ </td>
68
+ </tr>
69
+ </table>
@@ -0,0 +1,39 @@
1
+ <tr class="<%= cycle('even', 'odd') %>">
2
+ <td class="icon"><%= content_tag 'span', '', :class => "icon user#{user.gender == 'female' ? ' female' : ' male'}" %></td>
3
+ <td>
4
+ <%= render_icon(user.logged_in? ? 'online' : 'offline') %>
5
+ </td>
6
+ <td class="login"><%= user.login %></td>
7
+ <td class="name"><%= user.firstname %></td>
8
+ <td><%= user.lastname %></td>
9
+ <td class="email"><%= user.email %></td>
10
+ <td><%= _t(user.language, scope: 'translations', default: _t(:unknown)) %></td>
11
+ <td><%= user.last_sign_in_at.present? ? l(user.last_sign_in_at, :format => :default) : _t(:unknown) %></td>
12
+ <td class="role"><%= user.human_roles_string %></td>
13
+ <td class="tools">
14
+ <% permitted_to?(:destroy, :alchemy_admin_users) do %>
15
+ <%= link_to_confirmation_window(
16
+ '',
17
+ _t(:confirm_to_delete_user),
18
+ alchemy.admin_user_path(user),
19
+ :title => _t(:delete_user),
20
+ :class => "icon user_delete#{user.gender == 'female' ? ' female' : ' male'}"
21
+ ) %>
22
+ <% end %>
23
+ <% permitted_to?(:edit, :alchemy_admin_users) do %>
24
+ <%= link_to_overlay_window(
25
+ '',
26
+ alchemy.edit_admin_user_path(user),
27
+ {
28
+ :title => _t(:edit_user),
29
+ :overflow => true,
30
+ :size => '420x580'
31
+ },
32
+ {
33
+ :class => "icon user_edit#{user.gender == 'female' ? ' female' : ' male'}",
34
+ :title => _t(:edit_user)
35
+ }
36
+ ) %>
37
+ <% end %>
38
+ </td>
39
+ </tr>
@@ -0,0 +1,6 @@
1
+ <div id="user_edit">
2
+ <%= form_for [:admin, @user], :remote => true do |f| %>
3
+ <div id="errors"></div>
4
+ <%= render :partial => 'table', :locals => {:f => f} %>
5
+ <% end %>
6
+ </div>
@@ -0,0 +1,58 @@
1
+ <%= toolbar(
2
+ buttons: [
3
+ {
4
+ icon: 'user_add',
5
+ label: _t(:create_user),
6
+ url: alchemy.new_admin_user_path,
7
+ title: _t(:create_user),
8
+ hotkey: 'alt-n',
9
+ overlay_options: {
10
+ title: _t(:create_user),
11
+ size: "420x580"
12
+ },
13
+ if_permitted_to: [:new, :alchemy_admin_users]
14
+ }
15
+ ]
16
+ ) %>
17
+
18
+ <div id="archive_all">
19
+ <%= resources_header %>
20
+ <% if @users.any? %>
21
+
22
+ <table class="list" id="user_list">
23
+ <tr>
24
+ <th class="icon"></th>
25
+ <th class="login_status"></th>
26
+ <th class="login">
27
+ <%= sortable_column(Alchemy::User.human_attribute_name('login'), column: :login) %>
28
+ </th>
29
+ <th class="name">
30
+ <%= sortable_column(Alchemy::User.human_attribute_name('firstname'), column: :firstname) %>
31
+ </th>
32
+ <th>
33
+ <%= sortable_column(Alchemy::User.human_attribute_name('lastname'), column: :lastname) %>
34
+ </th>
35
+ <th class="email">
36
+ <%= sortable_column(Alchemy::User.human_attribute_name('email'), column: :email) %>
37
+ </th>
38
+ <th><%= Alchemy::User.human_attribute_name('language') %></th>
39
+ <th>
40
+ <%= sortable_column(Alchemy::User.human_attribute_name('last_sign_in_at'), column: :last_sign_in_at) %>
41
+ </th>
42
+ <th class="role"><%= Alchemy::User.human_attribute_name('alchemy_roles') %></th>
43
+ <th class="tools"></th>
44
+ </tr>
45
+ <%= render partial: 'alchemy/admin/users/user', collection: @users %>
46
+ </table>
47
+
48
+ <%= paginate @users %>
49
+
50
+ <% elsif params[:query] %>
51
+
52
+ <div class="info">
53
+ <%= render_icon('info') %>
54
+ <%= _t('No users found') %>
55
+ </div>
56
+
57
+ <% end %>
58
+ </div>
@@ -0,0 +1,6 @@
1
+ <div id="user_edit">
2
+ <%= form_for [:admin, @user], :remote => true do |f| %>
3
+ <div id="errors"></div>
4
+ <%= render :partial => 'table', :locals => {:f => f} %>
5
+ <% end %>
6
+ </div>
@@ -0,0 +1,15 @@
1
+ Willkommen in Alchemy!
2
+
3
+ Um die Inhalte Ihrer Webseite zu bearbeiten klicken Sie bitte auf folgenden Link:
4
+
5
+ <%= @url %>
6
+
7
+ Ihr Benutzername lautet: <%= @user.login %>
8
+
9
+ Aus Sicherheitsgründen stellen wir Ihr Passwort hier nicht dar.
10
+
11
+ Wenn Sie Ihr Passwort vergessen haben oder dies Ihr erster Login ist, gehen Sie bitte auf:
12
+
13
+ <%= alchemy.new_password_url %>
14
+
15
+ Viel Spaß mit Alchemy!
@@ -0,0 +1,15 @@
1
+ Welcome to Alchemy!
2
+
3
+ To manage your website open a browser and go to:
4
+
5
+ <%= @url %>
6
+
7
+ Your username is: <%= @user.login %>
8
+
9
+ For security reasons we do not show your password here.
10
+
11
+ If you forgot your password or this is your first login, please goto:
12
+
13
+ <%= alchemy.new_password_url %>
14
+
15
+ Have much fun with Alchemy!
@@ -0,0 +1,13 @@
1
+ Hallo <%= @user.name %>!
2
+
3
+ Ihnen wurde ein Benutzerkonto eingerichtet.
4
+
5
+ Ihr Benutzername lautet: <%= @user.login %>
6
+
7
+ Es wurde ein Zufallspasswort generiert. Aus Sicherheitsgründen wird dieses hier aber nicht angezeigt.
8
+
9
+ Klicken Sie bitte daher auf den folgenden Link (*), um sich ein neues Passwort zu vergeben:
10
+
11
+ <%= alchemy.new_password_url(email: @user.email) %>
12
+
13
+ *) Sollte dies nicht funktionieren, so kopieren Sie Sich bitte diesen Link und tragen Sie ihn in die Adresszeile Ihres Webbrowsers ein.
@@ -0,0 +1,13 @@
1
+ Greetings <%= @user.name %>!
2
+
3
+ A login was created for you.
4
+
5
+ Your username is: <%= @user.login %>
6
+
7
+ The password was randomly created. For security reasons it is not displayed here.
8
+
9
+ Please follow this link (*) to reset your password:
10
+
11
+ <%= alchemy.new_password_url(email: @user.email) %>
12
+
13
+ *) If this does not work, please copy the url and paste it into the address bar of your web browser.
@@ -0,0 +1,8 @@
1
+ Hallo <%= @user.fullname %>.
2
+
3
+ Sie haben angefordert Ihr Passwort zurückzusetzen. Dies kann durch anklicken des nachfolgenden Links bestätigt werden.
4
+
5
+ <%= alchemy.edit_password_url(@user, reset_password_token: @user.reset_password_token) %>
6
+
7
+ Wenn Sie diese Zurücksetzung nicht angefragt haben, dann können Sie diese E-Mail einfach ignorieren.
8
+ Ihr Passwort wird erst dann zurückgesetzt, wenn Sie den Link anklicken.
@@ -0,0 +1,8 @@
1
+ Hello <%= @user.name %>.
2
+
3
+ You has requested to change your password. Please confirm this by clicking the link below.
4
+
5
+ <%= alchemy.edit_password_url(@user, reset_password_token: @user.reset_password_token) %>
6
+
7
+ If you didn't request this, please ignore this email.
8
+ Your password won't change until you access the link above and create a new one.
@@ -0,0 +1,35 @@
1
+ <div id="login_box">
2
+ <div id="alchemy_greeting">
3
+ <%= image_tag("alchemy/alchemy-logo.png", :style => "width: 240px; height: 70px") %>
4
+ </div>
5
+ <div class="login_signup_box">
6
+ <% if @user.errors.blank? %>
7
+ <%= render_message do %>
8
+ <h1><%= _t 'Password reset' %></h1>
9
+ <p><%= _t 'Please enter a new password' %></p>
10
+ <% end %>
11
+ <% else %>
12
+ <div id="errors" style="display: block">
13
+ <%= devise_error_messages! %>
14
+ </div>
15
+ <% end %>
16
+ <%= form_for(:user, :url => password_path, :html => { :method => :put }) do |f| %>
17
+ <table>
18
+ <tr>
19
+ <td class="label"><%= f.label :password, _t("New password") %></td>
20
+ <td class="input"><%= f.password_field :password, :autofocus => true %></td>
21
+ </tr>
22
+ <tr>
23
+ <td class="label"><%= f.label :password_confirmation, _t("Confirm new password") %></td>
24
+ <td class="input"><%= f.password_field :password_confirmation %></td>
25
+ </tr>
26
+ <tr>
27
+ <td colspan="2" class="submit">
28
+ <%= f.hidden_field :reset_password_token %>
29
+ <%= f.button _t("Change password") %>
30
+ </td>
31
+ </tr>
32
+ </table>
33
+ <% end %>
34
+ </div>
35
+ </div>
@@ -0,0 +1,30 @@
1
+ <div id="login_box">
2
+ <div id="alchemy_greeting">
3
+ <%= image_tag("alchemy/alchemy-logo.png", :style => "width: 240px; height: 70px") %>
4
+ </div>
5
+ <div class="login_signup_box">
6
+ <% if @user.errors.blank? %>
7
+ <%= render_message do %>
8
+ <h1><%= _t 'Password reset' %></h1>
9
+ <p><%= _t 'Please enter your email address' %></p>
10
+ <% end %>
11
+ <% else %>
12
+ <div id="errors" style="display: block">
13
+ <%= devise_error_messages! %>
14
+ </div>
15
+ <% end %>
16
+ <%= form_for(:user, :url => reset_password_path, :html => { :method => :post }) do |f| %>
17
+ <table>
18
+ <tr>
19
+ <td class="label"><%= f.label :email %></td>
20
+ <td class="input"><%= f.email_field :email, :autofocus => true %></td>
21
+ </tr>
22
+ <tr>
23
+ <td colspan="2" class="submit">
24
+ <%= f.button _t("Send reset instructions") %>
25
+ </td>
26
+ </tr>
27
+ </table>
28
+ <% end %>
29
+ </div>
30
+ </div>
@@ -0,0 +1,48 @@
1
+ <div id="login_box">
2
+ <div id="alchemy_greeting">
3
+ <%= image_tag("alchemy/alchemy-logo.png", :style => "width: 240px; height: 70px") %>
4
+ </div>
5
+ <div class="login_signup_box">
6
+ <%= form_for :user, :url => {:action => :create}, :html => { :id => "login" } do |f| %>
7
+ <%= f.error_messages %>
8
+ <table>
9
+ <tr>
10
+ <td class="label">
11
+ <%= f.label :login %>
12
+ </td>
13
+ <td class="input">
14
+ <%= f.text_field :login, :class => 'thin_border', :autofocus => true %>
15
+ </td>
16
+ </tr>
17
+ <tr>
18
+ <td class="label">
19
+ <%= f.label :password %>
20
+ </td>
21
+ <td class="input">
22
+ <%= f.password_field :password, :class => 'thin_border' %>
23
+ <p class="foot_note">
24
+ <%= link_to _t('Forgot your password?'), new_password_path %>
25
+ </p>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td colspan="2" class="submit">
30
+ <%= hidden_field_tag 'user_screensize' %>
31
+ <%= f.button _t(:login), :class => 'button', :name => nil %>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+ <% end %>
36
+ </div>
37
+ </div>
38
+
39
+ <%- content_for :javascripts do -%>
40
+ <script type="text/javascript" charset="utf-8">
41
+ jQuery(function($) {
42
+ $('#user_login').focus();
43
+ $('#user_screensize').val(function() {
44
+ return screen.width+'x'+screen.height;
45
+ });
46
+ });
47
+ </script>
48
+ <%- end -%>
@@ -0,0 +1,14 @@
1
+ <div id="alchemy_greeting">
2
+ <%= image_tag("alchemy/alchemy-logo.png") %>
3
+ <h1><%= _t('Welcome to Alchemy') %></h1>
4
+ <p>
5
+ <%= _t("Please Signup") %>
6
+ </p>
7
+ </div>
8
+
9
+ <div id="user_signup" class="login_signup_box">
10
+ <%= form_for @user, :url => alchemy.signup_path do |f| %>
11
+ <%= f.error_messages %>
12
+ <%= render :partial => 'alchemy/admin/users/table', :locals => {:f => f} %>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,30 @@
1
+ authorization do
2
+ role :registered do
3
+ has_permission_on :alchemy_admin_users, :to => [:edit, :update] do
4
+ if_attribute :id => is {user.id}
5
+ end
6
+ end
7
+
8
+ role :author do
9
+ includes :registered
10
+ has_permission_on :alchemy_admin_users, :to => [:index]
11
+ end
12
+
13
+ role :editor do
14
+ includes :author
15
+ end
16
+
17
+ role :admin do
18
+ includes :editor
19
+ has_permission_on :alchemy_admin_users, :to => [:manage, :update_roles]
20
+ end
21
+ end
22
+
23
+ privileges do
24
+ # default privilege hierarchies to facilitate RESTful Rails apps
25
+ privilege :manage, :includes => [:create, :read, :update, :delete]
26
+ privilege :read, :includes => [:index, :show]
27
+ privilege :create, :includes => :new
28
+ privilege :update, :includes => :edit
29
+ privilege :delete, :includes => :destroy
30
+ end
@@ -0,0 +1,19 @@
1
+ Alchemy::Modules.register_module({
2
+ name: 'users',
3
+ engine_name: 'alchemy',
4
+ navigation: {
5
+ name: 'modules.users',
6
+ controller: 'alchemy/admin/users',
7
+ action: 'index',
8
+ icon: 'users',
9
+ sub_navigation: [{
10
+ name: 'modules.users',
11
+ controller: 'alchemy/admin/users',
12
+ action: 'index'
13
+ }]
14
+ }
15
+ })
16
+
17
+ Alchemy.user_class_name = 'Alchemy::User'
18
+ Alchemy.login_path = '/admin/login'
19
+ Alchemy.logout_path = '/admin/logout'