alchemy-devise 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +39 -0
- data/app/assets/stylesheets/alchemy/custom.scss +2 -0
- data/app/assets/stylesheets/alchemy/login.scss +55 -0
- data/app/assets/stylesheets/alchemy/users.scss +44 -0
- data/app/controllers/alchemy/admin/users_controller.rb +81 -0
- data/app/controllers/alchemy/base_controller_extension.rb +12 -0
- data/app/controllers/alchemy/passwords_controller.rb +31 -0
- data/app/controllers/alchemy/user_sessions_controller.rb +68 -0
- data/app/controllers/alchemy/users_controller.rb +46 -0
- data/app/mailers/alchemy/notifications.rb +33 -0
- data/app/models/alchemy/user.rb +178 -0
- data/app/views/alchemy/admin/users/_table.html.erb +69 -0
- data/app/views/alchemy/admin/users/_user.html.erb +39 -0
- data/app/views/alchemy/admin/users/edit.html.erb +6 -0
- data/app/views/alchemy/admin/users/index.html.erb +58 -0
- data/app/views/alchemy/admin/users/new.html.erb +6 -0
- data/app/views/alchemy/notifications/alchemy_user_created.de.text.erb +15 -0
- data/app/views/alchemy/notifications/alchemy_user_created.en.text.erb +15 -0
- data/app/views/alchemy/notifications/registered_user_created.de.text.erb +13 -0
- data/app/views/alchemy/notifications/registered_user_created.en.text.erb +13 -0
- data/app/views/alchemy/notifications/reset_password_instructions.de.text.erb +8 -0
- data/app/views/alchemy/notifications/reset_password_instructions.en.text.erb +8 -0
- data/app/views/alchemy/passwords/edit.html.erb +35 -0
- data/app/views/alchemy/passwords/new.html.erb +30 -0
- data/app/views/alchemy/user_sessions/new.html.erb +48 -0
- data/app/views/alchemy/users/new.html.erb +14 -0
- data/config/authorization_rules.rb +30 -0
- data/config/initializers/alchemy.rb +19 -0
- data/config/initializers/devise.rb +242 -0
- data/config/locales/alchemy.de.yml +44 -0
- data/config/locales/alchemy.en.yml +41 -0
- data/config/locales/devise.de.yml +58 -0
- data/config/locales/devise.en.yml +60 -0
- data/config/routes.rb +26 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20131015124700_create_alchemy_users.rb +33 -0
- data/db/migrate/20131225232042_add_alchemy_roles_to_alchemy_users.rb +19 -0
- data/lib/alchemy/devise.rb +6 -0
- data/lib/alchemy/devise/engine.rb +20 -0
- data/lib/alchemy/devise/version.rb +5 -0
- 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> </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,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,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'
|