Restricting access and activity is important to Role based sites. You will now add the ability to restrict access to certain parts of the site dependent upon which roles the user has been granted. You will also bootstrap an Admin (or Super User) account that will have the access ability to assign roles to other users.
Add the following methods to app/controller/application_controller.rb
Add these lines to same file to make the helper methods available to all controllers:
These methods basically return Boolean values that correspond to the method names. We will use these methods to determine, "Is there is a current user?", "Is the user the admin?", and "Is the user authorized to do this?".
The simple line "private" ensures these methods are private.
Add the before_filter line below to call a method before calling controller methods. This example shows how to restrict access to viewing and assigning roles to only users that are currently logged in.
Add the following line to the beginning of the class in app/controllers/roles_controller.rb:
Make sure you are logged out and navigate to http://localhost:3000/roles. You should see the flash message that you must be logged in and redirected to the log in page.
Add another rake task to bootstrap Admin and User roles to the database. The Admin role will grant users access to more restricted areas and methods. These tasks will also add an Admin account to the database. This account will be managed in a method User::authAdmin.
Add the following to lib/tasks/populate.rake:
Rake tasks follow dependency rules. The line :AdminRoleID => [:Role, :Admin] means the :Role and :Admin tasks will be called before :AdminRoleID task will run. Therefore, just run the :AdminRoleID task to run all of these tasks.
You should see the following output:
|The ":all" task depends on both :AuthServiceURL and :AdminRoldID. Running this task will run all tasks in the populate.rake file. Any new tasks created can easily be added to the hash of dependencies of the :all task.|
The authAdmin method below will check the Admin account credentials at log in. Add the method to app/models/user.rb:
|This is where the bootstrapped Admin account password is stored. This account is necessary because it will be the only account able to access and assign roles. Once another user is assigned the "Admin" role, this account can be deleted. However, only site administrators should have access to change this code.|
Replace the create method in app/controllers/sessions_controller.rb with the following:
Open the file app/views/roles/index.html.erb and add the code just below the <h1>Listing Roles<h1> header:
This code will call the admin? method to check if the current user has the admin role assigned to them. If they do, then the link will be displayed.
Check this by starting the rails server, log in with the credentials:
Now, on the http://localhost:3000/roles page, a link to "Assign Roles to Users" should be available.
Here you can see the two user accounts, admin and mark, and the roles assigned to each. Notice "mark" does not have the admin role.
Here is the roles index page when logged in with "mark". Notice there is no link to "Assign Roles to Users".
This is an good example of how to hide items in the view from users without proper access. This is good because a separate administration view is not needed, as admin options can just be added in line to the existing view. However, users can still access the assign roles page if they navigate to http://localhost:3000/role/assign. The above code just hides the link on the page. To restrict which methods are available to users, add the following filter to class in app/controllers/roles_controller.rb
This will restrict user's access to just the index location, http://localhost:3000/roles. Any other attempts to access role pages or methods will redirected and will display the "Unauthorized Access" error message.
|To make more methods available to users, such as "show", just add more methods to the hash in the filter (ex. before_filter :authorize, :except => [:index, :show]). Remove the except option to restrict all methods in the controller.|
Be sure no unauthorized changes to roles will occur by adding the following filter to app/controllers/users_controller.rb: