Changeset 153
- Timestamp:
- 11/28/05 07:00:51 (3 years ago)
- Files:
-
- plugins/user_engine/README (modified) (1 diff)
- plugins/user_engine/app/controllers/permission_controller.rb (modified) (3 diffs)
- plugins/user_engine/app/controllers/role_controller.rb (modified) (4 diffs)
- plugins/user_engine/app/controllers/user_controller.rb (modified) (7 diffs)
- plugins/user_engine/app/models/permission.rb (modified) (3 diffs)
- plugins/user_engine/app/models/role.rb (modified) (1 diff)
- plugins/user_engine/app/models/user.rb (modified) (1 diff)
- plugins/user_engine/app/views/permission/_form.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/permission/edit.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/permission/list.rhtml (modified) (2 diffs)
- plugins/user_engine/app/views/permission/new.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/permission/show.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/role/_form.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/role/edit.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/role/list.rhtml (modified) (3 diffs)
- plugins/user_engine/app/views/role/new.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/role/show.rhtml (modified) (3 diffs)
- plugins/user_engine/app/views/user/edit.rhtml (deleted)
- plugins/user_engine/app/views/user/edit_user.rhtml (copied) (copied from branches/user_engine/app/views/user/edit_user.rhtml)
- plugins/user_engine/app/views/user/list.rhtml (modified) (2 diffs)
- plugins/user_engine/app/views/user/new.rhtml (modified) (1 diff)
- plugins/user_engine/app/views/user/show.rhtml (modified) (1 diff)
- plugins/user_engine/db/migrate (copied) (copied from branches/user_engine/db/migrate)
- plugins/user_engine/db/migrate/001_initial_schema.rb (copied) (copied from branches/user_engine/db/migrate/001_initial_schema.rb)
- plugins/user_engine/db/migrate/002_added_omnipotent_flag_to_roles.rb (copied) (copied from branches/user_engine/db/migrate/002_added_omnipotent_flag_to_roles.rb)
- plugins/user_engine/db/migrate/003_added_system_roles.rb (copied) (copied from branches/user_engine/db/migrate/003_added_system_roles.rb)
- plugins/user_engine/db/schema.rb (modified) (2 diffs)
- plugins/user_engine/init_engine.rb (modified) (1 diff)
- plugins/user_engine/lib/user_engine.rb (modified) (8 diffs)
- plugins/user_engine/lib/user_engine/authorized_system.rb (modified) (4 diffs)
- plugins/user_engine/lib/user_engine/authorized_user.rb (modified) (4 diffs)
- plugins/user_engine/public/stylesheets/user_engine.css (modified) (3 diffs)
- plugins/user_engine/tasks/user_engine.rake (modified) (5 diffs)
- plugins/user_engine/test/fixtures/permissions.yml (modified) (1 diff)
- plugins/user_engine/test/fixtures/permissions_roles.yml (modified) (1 diff)
- plugins/user_engine/test/fixtures/roles.yml (modified) (1 diff)
- plugins/user_engine/test/fixtures/users.yml (modified) (3 diffs)
- plugins/user_engine/test/fixtures/users_roles.yml (modified) (1 diff)
- plugins/user_engine/test/functional/permission_controller_test.rb (copied) (copied from branches/user_engine/test/functional/permission_controller_test.rb)
- plugins/user_engine/test/functional/role_controller_test.rb (copied) (copied from branches/user_engine/test/functional/role_controller_test.rb)
- plugins/user_engine/test/functional/user_controller_test.rb (copied) (copied from branches/user_engine/test/functional/user_controller_test.rb)
- plugins/user_engine/test/test_helper.rb (modified) (2 diffs)
- plugins/user_engine/test/unit/permission_test.rb (modified) (1 diff)
- plugins/user_engine/test/unit/role_test.rb (copied) (copied from branches/user_engine/test/unit/role_test.rb)
- plugins/user_engine/test/unit/user_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/user_engine/README
r97 r153 1 1 = UserEngine: Login + Roles 2 2 3 The UserEngine extends the LoginEngine with a very, *very* simple implemntation of RBAC - role based access control. As well as the 'User' object, the UserEngine provides Permission objects, and Role objects. Each User can have many Roles, and each Role is assoociated with many Permissions. A Permission is simple a controller/action pair. A Role which is associated with some permission has access to that specific controller/action, i.e. and Role associated with the Permission object "user/home" will be allowed to call that action. 3 The UserEngine extends the LoginEngine with a very, *very* simple implementation of RBAC - role based access control. As well as the 'User' object, the UserEngine provides Permission objects, and Role objects. Each User can have many Roles, and each Role is associated with many Permissions. A Permission is simple a controller/action pair. A Role which is associated with some permission has access to that specific controller/action, i.e. and Role associated with the Permission object "user/home" will be allowed to call that action. 4 5 6 === Not the One True RBAC system 7 8 We'll make this point at the beginning, so there can be no doubt - this is *not* a full permission system. The UserEngine only controls which users have the right to hit which controller/action pairs. It will not control access to data at all, so for instance you cannot use it to give users the ability to edit only a subset of your data object (unless that subset is controlled via different controller actions). 9 4 10 5 11 6 12 = Installing 7 13 8 0. Create your Rails application, set up your databases, grab the Engines plugin and the LoginEngine, and install them. 9 10 1. Install the UserEngine into your vendor/plugins directory 11 12 2. Modify your Engines.start call in config/environment.rb - if you have specifically specified which Engines to start, ensure that you add :user (or :user_engine). The important point here is to note that the UserEngine must be started *after* the LoginEngine, since it will override a small amount of the behaviour in the latter. The end of your environment.rb file should look something like this: 13 14 Engines.start :login, :user 15 16 or 17 18 Engines.start :login 19 Engines.start :user 20 21 or simply: 22 23 Engines.start # note that this use assumes that you haven't renamed the user_engine 24 # to anything which would come before 'login_engine' alphabetically 25 26 27 3. Edit your application.rb file so it looks something like the following (note the new <tt>include UserEngine</tt> and the changed +before_filter+): 28 29 class ApplicationController < ActionController::Base 30 include LoginEngine 31 include UserEngine 32 33 helper :user 34 model :user 35 36 before_filter :authorize_action 37 end 38 39 4. Edit your application_helper.rb file: 40 41 module ApplicationHelper 42 include LoginEngine 43 include UserEngine 44 end 45 46 5. Since the UserEngine overrides some of the default behaviour in the LoginEngine, if you have made your own modifications within your app directory, you'll probably want to examine these changes to make sure that your own customisations will still operate as expected. You'll need to look at the following: 14 1. Create your Rails application, set up your databases, grab the Engines plugin and the LoginEngine, and install them. 15 16 2. Install the UserEngine into your vendor/plugins directory 17 18 3. Modify your Engines.start call in config/environment.rb - if you have specifically specified which Engines to start, ensure that you add :user (or :user_engine). The important point here is to note that the UserEngine must be started *after* the LoginEngine, since it will override a small amount of the behaviour in the latter. The end of your environment.rb file should look something like this: 19 20 Engines.start :login, :user 21 22 or 23 24 Engines.start :login 25 Engines.start :user 26 27 or simply: 28 29 Engines.start # note that this use assumes that you haven't renamed the user_engine 30 # to anything which would come before 'login_engine' alphabetically 31 32 33 4. Edit your application.rb file so it looks something like the following (note the new <tt>include UserEngine</tt> and the changed +before_filter+): 34 35 class ApplicationController < ActionController::Base 36 include LoginEngine 37 include UserEngine 38 39 helper :user 40 model :user 41 42 before_filter :authorize_action 43 end 44 45 5. Edit your application_helper.rb file: 46 47 module ApplicationHelper 48 include LoginEngine 49 include UserEngine 50 end 51 52 6. Perform any configuration you might need. You'll probably want to set these values in environment.rb (before the call to Engines.start): 53 54 module UserEngine 55 config :admin_login, "the login name for your administrator user" 56 config :admin_email, "an email address for your administrator" 57 config :admin_password, "your initial admin password" 58 end 59 60 7. Initialize the database tables. You must ensure that the tables for the LoginEngine are present since this engine builds on top of them. You will probably get a warning if this is your first installation of the User Engine, indicating that you don't have an Admin role - that's fine, we'll be creating it later. You can either use the engine migrations by calling: 61 62 rake engine_migrate 63 64 to move all engines to their latest versions, or 65 66 rake engine_migrate ENGINE=user 67 68 to migrate only this engine. Alternatively, if you just want to load the full schema information for the User and LoginEngines, run 69 70 rake import_user_engine_schema 71 72 8. Run the rake task to install the default Roles and administrator user. This will also create a new user with the Admin role - the default login (if you didn't set it in step 6) is 'admin' and the password is 'testing'. Make sure you change it!: 73 74 rake bootstrap 75 76 9. The UserEngine includes a method to check whether or not the system roles created above are still intact. You should typically call this each time the server starts, by placing the following call at the bottom of your environment.rb: 77 78 UserEngine.check_system_roles 79 80 10. The UserEngine provides a default stylesheet and a small javascript helper file (used in the Role#edit action), so you'll probably want to include the former and almost certainly the latter in your application's layout. Add the following lines: 81 82 <%= engine_stylesheet "user" %> 83 <%= engine_javascript "user" %> 84 85 11. Remove any existing sessions (since they might interfere with the login process), and start the server and log using your administrator login and password (if you didn't set one explicitly in your configuration, the defaults are 'admin'/'testing' - make sure you change them!) and go to http://localhost:3000/user/list to see a list of all the users. From there you can create new users, view roles & permissions, and play around... 86 87 12. Since the UserEngine overrides some of the default behaviour in the LoginEngine, if you have made your own modifications within your app directory, you'll probably want to examine these changes to make sure that your own customisations will still operate as expected. You'll need to look at the following: 47 88 48 89 * The UserEngine's models/user.rb model will override the default given in LoginEngine. If you have your own app/models/user.rb file, you'll need to include UserEngine::AuthorizedUser in your file. 49 90 * The UserController#edit action has been overriden to know about Roles. See user_engine/app/user_controller.rb for details. 50 91 * Many new methods for administrating users, roles and permissions have been provided - again, see user_engine/app/user_controller.rb. 51 * If you have overriden any User views, look at the corresponding views in the UserEngine to see if there are any changes you wish to include in your own versions. 52 53 6. Perform any configuration you might need. You'll probably want to set these values in environment.rb (before the call to Engines.start): 54 55 module UserEngine 56 config :admin_name, "the login name for your administrator user" 57 config :admin_email, "an email address for your administrator" 58 end 59 60 7. Run the rake task to install the default Roles and administrator user: 61 62 rake bootstrap 63 64 8. Start the server and log in - go to http://localhost:3000/user/list to see a list of all the users... 92 * If you have overridden any User views, look at the corresponding views in the UserEngine to see if there are any changes you wish to include in your own versions. 93 94 95 96 97 98 99 = Configuration 100 101 A number of configuration parameters are available to allow to you control 102 how the data is stored, should you be unhappy with the defaults. These are 103 outlined below. You should almost certainly customize the <tt>:admin_email</tt> 104 value in your environment.rb file, i.e.: 105 106 module LoginEngine 107 config :salt, 'your salt value' 108 end 109 module UserEngine 110 config :admin_email, 'admin@megacorp.com' 111 end 112 Engines.start :login, :user 113 114 115 === Configuration Options 116 117 +role_table+:: the name of the table to store Role objects in. Defaults to 118 "roles" (or "role" if you have disabled pluralization.) 119 +permission_table+:: the name of the table to store Permission objects 120 in. Defaults to "permissions" (or "permission" if 121 you have disabled pluralization.) 122 +user_role_table+:: the join table for users and roles. Defaults to 123 <user_table>_<role_table>. (User table is specified in 124 the LoginEngine configuration). 125 +permission_role_table+:: the join table for roles and permissions. Defaults 126 to <permission_table>_<role_table>. 127 +guest_role_name+:: the name for the Guest Role. Defaults to "Guest". 128 +user_role_name+:: the name for the User Role. Defaults to "User". 129 +admin_role_name+:: the name for the Admin Role. Defaults to "Admin". 130 +admin_login+:: the login ID for the initial Admin user. Defaults to "admin". 131 +admin_email+:: the email address of the site administrator. Defaults to 132 "admin@your.company". 133 +login_page+:: a Hash describing where the login page. Defaults to 134 {:controller => 'user', :action => 'login'} 135 +steath+:: a boolean flag to indicate whether or not the system should 136 display helpful messages about authorized roles when they are 137 denied access to an action, or if it should simply deny the 138 user access without revealing which roles can access that action. 139 Defaults to false (i.e. DO show helpful messages). 140 141 142 = Usage 143 144 === Users 145 Once you have logged in as an administrator, you can go to /user/list to get a list of all users. Here you can also create new users (/user/new) and edit the details of the users in your system. 146 147 If you edit a user (/user/edit_user/+id+), you can now not only change user details and passwords, but also specify which roles the user has. 148 149 === Roles 150 151 Three distinct Role objects are initially created when you bootstrap the UserEngine 152 153 * Guest, with permissions to login, signup and retrieve forgotten passwords 154 * User, with permissions to logout, to to /user/home, change passwords and edit their own information 155 * Admin, with permissions to edit all users, list users, edit all roles, edit permissions, and so on. 156 157 New roles can easily be created at /role/new, where you can select exactly which permissions this role should have. A similar interface is presented in /role/edit/+id+. For instance, if you have a ReportController with the actions +view+ and +edit+, you might create two new Roles - 'ReportViewer' and ReportEditor'. The only permissions the ReportViewer has will be report/view, and the only permission assigned to ReportEditor is similarly report/edit. You can now assign the ReportViewer role to as many users as will need to be able to view reports, but only give the ReportEditor to users who should also be able to edit reports. 158 159 It's worth noting that this point that if a user has the ability to edit other users (/user/edit_user), they will be able to assign Roles (including the Admin role) to anyone they please. Similarly, users who can edit roles (/role/edit) can add any permissions at all to any Role within the system. Therefore you (as the system administrator) must be *very* careful about allowing these permissions on any role other than Admin. 160 161 In general, you should not give normal users *any* permissions other than the default ones, and permissions to any controllers specific to *your* application. 162 163 === Permissions 164 165 While you can create permissions using the regular scaffold-style interface, it is better to avoid manually creating them if possible. Instead, a method is provided for automatically scanning your controllers and ensuring that there exists a Permission object for each controller-action pair. This method is <tt>Permission.sychronize_controllers</tt> (or just <tt>Permission.sync</tt> as a shorthand), and can be called either from the console, or as a rake task: 166 167 rake sync_permissions 168 169 It may be worth noting that currently this method will deliberately *never* delete any permission objects from your system, even if the method is no longer present. 170 171 == Helper methods 172 173 The UserEngine provides several helpers which understand permissions and roles, to be used in your views. The two most important are outlined below. 174 175 === link_if_authorized(controller, action) 176 177 <tt>link_if_authorized</tt> will produce a link to an action *only* if the currently logged-in user has permission to perform the given action. It can be passed options to show the text (without a link) if the user is not authorized, or to wrap the text in another HTML element (i.e an li element) if a link is to be produced. 178 179 === authorized?(controller, action) 180 181 <tt>authorized?</tt> will simply return true or false to reflect the current user's authorization for the given action. This method can also take a block, which will only be performed if the user is authorized for the given action. In this manner you can control the display chunks of HTML or certain processing based on the permissions of the current user. 182 183 184 = LICENSE 185 186 Copyright (c) 2005 James Adam 187 188 This is the MIT license, the license Ruby on Rails itself is licensed 189 under. 190 191 Permission is hereby granted, free of charge, to any person obtaining 192 a copy of this software and associated documentation files (the 193 "Software"), to deal in the Software without restriction, including 194 without limitation the rights to use, copy, modify, merge, publish, 195 distribute, sublicense, and/or sell copies of the Software, and to permit 196 persons to whom the Software is furnished to do so, subject to the 197 following conditions: 198 199 The above copyright notice and this permission notice shall be included 200 in all copies or substantial portions of the Software. 201 202 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 203 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 205 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 206 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 207 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 208 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. plugins/user_engine/app/controllers/permission_controller.rb
r97 r153 1 # Copyright (c) 2005 James Adam 2 # 3 # This is the MIT license, the license Ruby on Rails itself is licensed 4 # under. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining 7 # a copy of this software and associated documentation files (the 8 # "Software"), to deal in the Software without restriction, including 9 # without limitation the rights to use, copy, modify, merge, publish, 10 # distribute, sublicense, and/or sell copies of the Software, and to permit 11 # persons to whom the Software is furnished to do so, subject to the 12 # following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included 15 # in all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 # The PermissionController provides methods for manipulating Permission 27 # objects from the web interface. 1 28 class PermissionController < ApplicationController 2 29 3 30 # We shouldn't accept GET requests that modify data. 4 verify :method => :post, :only => %w( create updatedestroy)31 verify :method => :post, :only => %w(destroy) 5 32 6 33 # Will redirect to the list view 7 34 def index 8 35 redirect_to :action => "list" 9 36 end 10 37 38 # Displays a paginated list of all Permission objects 11 39 def list 12 40 @content_columns = Permission.content_columns 13 @permission_pages, @permissions = paginate :permission, : per_page => 1541 @permission_pages, @permissions = paginate :permission, :order => 'id', :per_page => 15 14 42 end 15 43 44 # Displays a single Permission object, by the id given. 16 45 def show 17 46 if (@permission = find_permission(params[:id])) … … 22 51 end 23 52 53 # Creates a new Permission object. Note that this is not the recommended 54 # way of creating Permission objects - instead you should use 55 # Permission.sync to add them automatically from your application 24 56 def new 25 @permission = Permission.new 26 end 27 28 def create 29 @permission = Permission.new(@params[:permission]) 30 if @permission.save 31 flash[:notice] = 'Permission was successfully created.' 32 redirect_to :action => 'list' 33 else 34 render_action 'new' 57 case request.method 58 when :get 59 @permission = Permission.new 60 when :post 61 @permission = Permission.new(@params[:permission]) 62 if @permission.save 63 flash[:notice] = 'Permission was successfully created.' 64 redirect_to :action => 'list' 65 else 66 render_action 'new' 67 end 35 68 end 36 69 end 37 70 71 # Edits a Permission object 38 72 def edit 39 if (@permission = find_permission(params[:id])).nil? 40 redirect_back_or_default :action => 'list' 73 case request.method 74 when :get 75 if (@permission = find_permission(params[:id])).nil? 76 redirect_back_or_default :action => 'list' 77 end 78 when :post 79 if (@permission = find_permission(params[:id])) 80 if @permission.update_attributes(@params[:permission]) 81 flash[:notice] = 'Permission was successfully updated.' 82 redirect_to :action => 'show', :id => @permission 83 else 84 render_action 'edit' 85 end 86 else 87 redirect_back_or_default :action => 'list' 88 end 41 89 end 42 90 end 43 91 44 def update 45 if (@permission = find_permission(params[:id])) 46 if @permission.update_attributes(@params[:permission]) 47 flash[:notice] = 'Permission was successfully updated.' 48 redirect_to :action => 'show', :id => @permission 49 else 50 render_action 'edit' 51 end 52 else 53 redirect_back_or_default :action => 'list' 54 end 55 end 56 92 # Destroys a Permission Object 57 93 def destroy 58 94 if (@permission = find_permission(params[:id])) 59 95 @permission.destroy 96 flash[:notice] = "Permission '#{@permission.path}' deleted." 60 97 redirect_to :action => 'list' 61 98 else … … 64 101 end 65 102 66 private 103 protected 104 # A helper method to find Permission objects by ID, and insert 105 # appropriate error messages into the flash if it couldn't be 106 # found. 67 107 def find_permission(id) 68 108 begin plugins/user_engine/app/controllers/role_controller.rb
r97 r153 1 # Copyright (c) 2005 James Adam 2 # 3 # This is the MIT license, the license Ruby on Rails itself is licensed 4 # under. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining 7 # a copy of this software and associated documentation files (the 8 # "Software"), to deal in the Software without restriction, including 9 # without limitation the rights to use, copy, modify, merge, publish, 10 # distribute, sublicense, and/or sell copies of the Software, and to permit 11 # persons to whom the Software is furnished to do so, subject to the 12 # following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included 15 # in all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 27 # The RoleController allows Role objects to be manipulated via the 28 # web interface 1 29 class RoleController < ApplicationController 2 30 3 31 # We shouldn't accept GET requests that modify data. 4 verify :method => :post, :only => %w( create updatedestroy)32 verify :method => :post, :only => %w(destroy) 5 33 34 # Redirects to the list action 6 35 def index 7 36 redirect_to :action => 'list' 8 37 end 9 38 39 # Displays a paginated list of Role objects 10 40 def list 11 41 @content_columns = Role.content_columns … … 13 43 end 14 44 45 # Displays a single Role object by given id. 15 46 def show 16 47 if (@role = find_role(params[:id])) … … 30 61 end 31 62 63 # Creates a new Role object with the given parameters. 32 64 def new 33 @role = Role.new 34 end 35 36 def create 37 @role = Role.new(params[:role]) 38 if @role.save 39 flash[:notice] = 'Role was successfully created.' 40 redirect_to :action => 'list' 41 else 42 render_action 'new' 65 case request.method 66 when :get 67 @role = Role.new 68 when :post 69 @role = Role.new(params[:role]) 70 if @role.save 71 flash[:notice] = 'Role was successfully created.' 72 redirect_to :action => 'list' 73 else 74 render_action 'new' 75 end 43 76 end 44 77 end 45 78 79 # Edit a Role object 46 80 def edit 47 if (@role = find_role(params[:id])) 48 # load up the controllers 49 @all_permissions = Permission.find_all 81 case request.method 82 when :get 83 if (@role = find_role(params[:id])) 84 # load up the controllers 85 @all_permissions = Permission.find_all 50 86 51 # split it up into controllers 52 @all_actions = {} 53 @all_permissions.each { |permission| 54 @all_actions[permission.controller] ||= [] 55 @all_actions[permission.controller] << permission 56 } 57 else 58 redirect_back_or_default :action => 'list' 87 # split it up into controllers 88 @all_actions = {} 89 @all_permissions.each { |permission| 90 @all_actions[permission.controller] ||= [] 91 @all_actions[permission.controller] << permission 92 } 93 else 94 redirect_back_or_default :action => 'list' 95 end 96 when :post 97 if (@role = find_role(params[:id])) 98 # update the action permissions 99 permission_keys = params.keys.select { |k| k =~ /^permissions_/ } 100 permissions = permission_keys.collect { |k| params[k] } 101 102 begin 103 permissions.collect! { |perm_id| Permission.find(perm_id) } 104 105 # just wipe them all and re-build 106 @role.permissions.clear 107 108 permissions.each { |perm| 109 if !@role.permissions.include?(perm) 110 @role.permissions << perm 111 end 112 } 113 114 # save the object 115 if @role.update_attributes(params[:role]) 116 flash[:notice] = 'Role was successfully updated.' 117 redirect_to :action => 'show', :id => @role 118 else 119 flash[:message] = 'The role could not be updated.' 120 render :action => 'edit' 121 end 122 rescue ActiveRecord::RecordNotFound => e 123 flash[:message] = 'Permission not found!' 124 render :action => 'edit' 125 end 126 else 127 redirect_back_or_default :action => 'list' 128 end 59 129 end 60 130 end 61 131 62 def update 63 if (@role = find_role(params[:id])) 64 # update the action permissions 65 permission_keys = params.keys.select { |k| k =~ /^permissions_/ } 66 permissions = permission_keys.collect { |k| params[k] } 67 permissions.collect! { |perm_id| Permission.find(perm_id) } 68 69 # just wipe them all and re-build 70 @role.permissions.clear 71 72 permissions.each { |perm| 73 if !@role.permissions.include?(perm) 74 @role.permissions << perm 75 end 76 } 77 78 # save the object 79 if @role.update_attributes(params[:role]) 80 flash[:notice] = 'Role was successfully updated.' 81 redirect_to :action => 'show', :id => @role 82 else 83 render_action 'edit' 84 end 85 else 86 redirect_back_or_default :action => 'list' 87 end 88 end 89 132 # Destroy a given Role object 90 133 def destroy 91 134 if (@role = find_role(params[:id])) 92 @role.destroy 93 redirect_to :action => 'list' 135 begin 136 @role.destroy 137 flash[:notice] = "Role '#{@role.name}' has been deleted." 138 redirect_to :action => 'list' 139 rescue UserEngine::SystemProtectionError => e 140 flash[:message] = "Cannot destroy the system role '#{@role.name}'!" 141 redirect_to :action => 'list' 142 end 94 143 else 95 144 redirect_back_or_default :action => 'list' … … 97 146 end 98 147 99 pr ivate148 protected 100 149 # A convenience method to find a Role, and add any errors to the flash if 101 150 # the Role is not found. plugins/user_engine/app/controllers/user_controller.rb
r97 r153 1 # Copyright (c) 2005 James Adam 2 # 3 # This is the MIT license, the license Ruby on Rails itself is licensed 4 # under. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining 7 # a copy of this software and associated documentation files (the 8 # "Software"), to deal in the Software without restriction, including 9 # without limitation the rights to use, copy, modify, merge, publish, 10 # distribute, sublicense, and/or sell copies of the Software, and to permit 11 # persons to whom the Software is furnished to do so, subject to the 12 # following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included 15 # in all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 27 # The UserEngine UserController overrides the UserController from the 28 # LoginEngine to give user management methods (list, edit_user, etc) 1 29 class UserController < ApplicationController 30 2 31 # Ensure that these methods CANNOT be called via a GET request 3 32 verify :method => :post, :only => %w(edit_roles change_password_for_user delete_user) 4 33 34 # Displays a paginated list of Users 5 35 def list 6 36 @content_columns = user_content_columns_to_display … … 20 50 if (@user = find_user(params[:id])) 21 51 @all_roles = Role.find_all.select { |r| r.name != UserEngine.config(:guest_role_name) } 22 if request.method == :get 23 render :action => "edit" 24 else 25 @user.attributes = params[:user].delete_if { |k,v| not LoginEngine.config(:changeable_fields).include?(k) } 26 if @user.save 27 flash.now[:notice] = "Your details have been updated" 28 else 29 flash.now[:warning] = "Your details could not be updated!" 30 end 31 render :action => "edit" 52 case request.method 53 when :get 54 when :post 55 @user.attributes = params[:user].delete_if { |k,v| not LoginEngine.config(:changeable_fields).include?(k) } 56 if @user.save 57 flash.now[:notice] = "Details for user '#{@user.login}' have been updated" 58 else 59 flash.now[:warning] = "Details could not be updated!" 60 end 32 61 end 33 62 else … … 36 65 end 37 66 67 # Edit the roles for a given User object. 38 68 # A user typically shouldn't be allowed to edit their own roles, since they could 39 69 # assign themselves as Admins and then do anything. Therefore, keep this method … … 50 80 51 81 @user.save 52 flash[:notice] = "Roles updated for user '#{@user.login}' "82 flash[:notice] = "Roles updated for user '#{@user.login}'." 53 83 end 54 84 rescue 55 flash[:warning] = ' Your roles could not be edited at this time. Please retry.'85 flash[:warning] = 'Roles could not be edited at this time. Please retry.' 56 86 ensure 57 87 redirect_to :back … … 65 95 def change_password_for_user 66 96 if (@user = find_user(params[:id])) 67 change_password_for(@user)68 else69 redirect_back_or_default :action => 'list'70 end97 do_change_password_for(@user) 98 flash[:notice] = "Password for user '#{@user.login}' has been updated." 99 end 100 redirect_back_or_default :action => 'list' 71 101 end 72 102 73 # Delete a user103 # Delete an arbitrary user 74 104 def delete_user 75 105 if (@user = find_user(params[:id])) 76 106 do_delete_user(@user) 107 flash[:notice] = "User '#{@user.login}' has been deleted." 77 108 end 78 redirect_ back_or_default:action => 'list'109 redirect_to :action => 'list' 79 110 end 80 111 … … 89 120 end 90 121 91 122 # Create a new User, skipping any verification by email. 92 123 def new 93 if request.method == :get 94 @user = User.new 95 render 96 return true 97 else 98 99 @user = User.new(params[:user]) 100 begin 101 User.transaction(@user) do 102 @user.new_password = true 103 @user.verified = 1 # skip verification, because we are ADMIN! 104 if @user.save 105 flash[:notice] = 'User creation successful.' 106 redirect_to :back 124 case request.method 125 when :get 126 @user = User.new 127 render 128 return true 129 when :post 130 @user = User.new(params[:user]) 131 begin 132 User.transaction(@user) do 133 @user.new_password = true 134 @user.verified = 1 # skip verification, because we are ADMIN! 135 if @user.save 136 flash[:notice] = 'User creation successful.' 137 redirect_to :action => 'list' 138 end 107 139 end 140 rescue Exception => e 141 flash.now[:notice] = nil 142 flash.now[:warning] = 'Error creating account: confirmation email not sent' 143 logger.error e 108 144 end 109 rescue Exception => e110 flash.now[:notice] = nil111 flash.now[:warning] = 'Error creating account: confirmation email not sent'112 logger.error e113 end114 145 end 115 146 end 116 147 117 148 118 private 149 protected 150 # A convenience method we can use to control the columns of the User object that 151 # we might ever to see, and hide all other ones. 119 152 def user_content_columns_to_display 120 153 # we don't want people to see the passwords (even though they) 121 154 # are hashed up... 122 @content_columns = User.content_columns123 @content_columns.delete_if { |c| ["salted_password", "salt", "security_token", "token_expiry"].include?(c.name) }155 desired_columns = ["salted_password", "salt", "security_token", "token_expiry"] 156 User.content_columns.delete_if { |c| desired_columns.include?(c.name) } 124 157 end 125 158 … … 130 163 User.find(id) 131 164 rescue ActiveRecord::RecordNotFound 132 flash[:message] = "There is no use dwith ID ##{id}"165 flash[:message] = "There is no user with ID ##{id}" 133 166 nil 134 167 end plugins/user_engine/app/models/permission.rb
r97 r153 1 #-------------------------------------------------------------------------- 1 # Copyright (c) 2005 James Adam 2 # 3 # This is the MIT license, the license Ruby on Rails itself is licensed 4 # under. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining 7 # a copy of this software and associated documentation files (the 8 # "Software"), to deal in the Software without restriction, including 9 # without limitation the rights to use, copy, modify, merge, publish, 10 # distribute, sublicense, and/or sell copies of the Software, and to permit 11 # persons to whom the Software is furnished to do so, subject to the 12 # following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included 15 # in all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 2 27 # The Permission class is simply a database representation of each 3 28 # controller/action pair. The association between a Role and a Permission 4 29 # instance indicates that such a Role is authorised to call the 5 30 # controller/action pair which that Permission represents. 6 #--------------------------------------------------------------------------7 31 class Permission < ActiveRecord::Base 32 8 33 set_table_name UserEngine.config(:permission_table) 9 34 has_and_belongs_to_many :roles, :join_table => UserEngine.config(:permission_role_table) 10 35 36 validates_presence_of :controller, :action 37 38 #-- 39 # Class methods 40 #++ 11 41 class << self 42 12 43 # Ensure that the table has one entry for each controller/action pair 13 44 def synchronize_with_controllers … … 22 53 # outside of the framework environment...? 23 54 controller_files += Dir[Engines.config(:root) + "/**/app/controllers/**/*_controller.rb"] 24 25 # TODO: plugins. difficult because there's no fixed path...26 55 27 56 # we need to load all the controllers... … … 40 69 end 41 70 42 #def self.sync() self.synchronize_with_controllers end # alias 71 #-- 72 # A shorthand alias 73 #++ 43 74 alias :sync :synchronize_with_controllers 44 75 45 76 end 46 77 47 # def controller 48 # raise Exception.new("Empty path in Permission ##{id}!") if path.empty? 49 # @controller ||= path.split("/")[0..-2].join("/") 50 # end 51 52 # def action 53 # raise Exception.new("Empty path in Permission ##{id}!") if path.empty? 54 # @action ||= path.split("/").last 55 # end 56 78 # Returns the full path which this Permission object represents 57 79 def path 58 80 [controller, action].join("/") plugins/user_engine/app/models/role.rb
r97 r153 1 #-------------------------------------------------------------------------- 1 # Copyright (c) 2005 James Adam 2 # 3 # This is the MIT license, the license Ruby on Rails itself is licensed 4 # under. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining 7 # a copy of this software and associated documentation files (the 8 # "Software"), to deal in the Software without restriction, including 9 # without limitation the rights to use, copy, modify, merge, publish, 10 # distribute, sublicense, and/or sell copies of the Software, and to permit 11 # persons to whom the Software is furnished to do so, subject to the 12 # following conditions: 13 # 14 # The above copyright notice and this permission notice shall be included 15 # in all copies or substantial portions of the Software. 16 # 17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 23 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 2 27 # The Role class represents an abstract set of allowable behaviours within 3 28 # an application. Each Role is associated with a number of Permissions (or 4 29 # controller/action objects), and such associations indicate what actions 5 30 # users using this application are allowed to perform. 6 #--------------------------------------------------------------------------7 31 class Role < ActiveRecord::Base 8 32 has_and_belongs_to_many :users, :class_name => "User", :join_table => UserEngine.config(:user_role_table) 9 33 has_and_belongs_to_many :permissions, :join_table => UserEngine.config(:permission_role_table) 34 35 validates_length_of :name, :minimum => 3 36 validates_uniqueness_of :name 37 38 # there can only be one omnipotent role. 39 def validate_on_create 40 if self.omnipotent? && Role.find_by_omnipotent(1) 41 errors.add_to_base("There can only be one omnipotent role.") 42 end
