Restrict access to web accessible paths

We'll explore the three authentication mechanisms Odoo provides for routes in this recipe. We'll define routes with different authentication mechanisms in order to show their differences.

Getting ready

As we extend code from the previous recipe, we'll also depend on the library.book model of Chapter 4, Application Models, so you should get its code in order to proceed.

How to do it…

Define handlers in controllers/main.py:

  1. Add a path that shows all books:
        @http.route('/my_module/all-books', type='http', auth='none')
        def all_books(self):
            records = request.env['library.book'].sudo().search([])
            result = '<html><body><table><tr><td>'
            result += '</td></tr><tr><td>'.join(
                      records.mapped('name'))
            result += '</td></tr></table></body></html>'
            return result
  2. Add a path that shows all books and indicates which was written by the current user, if any:
    @http.route('/my_module/all-books/mark-mine', type='http', auth='public')
    def all_books_mark_mine(self):
       records = request.env['library.book'].sudo().search([])
            result = '<html><body><table>'
            for record in records:
                result += '<tr>'
                if record.author_ids & request.env.user.partner_id:
                    result += '<th>'
                else:
                    result += '<td>'
                result += record.name
                if record.author_ids & request.env.user.partner_id:
                    result += '</th>'
                else:
                    result += '</td>'
                result += '</tr>'
            result += '</table></body></html>'
            return result
  3. Add a path that shows the current user's books:
        @http.route('/my_module/all-books/mine', type='http', 
            auth='user')
        def all_books_mine(self):
            records = request.env['library.book'].search([
                ('author_ids', 'in',
                request.env.user.partner_id.ids),
            ])
            result = '<html><body><table><tr><td>'
            result += '</td></tr><tr><td>'.join(
                      records.mapped('name'))
            result += '</td></tr></table></body></html>'
            return result

With this code, the paths /my_module/all_books and /my_module/all_books/mark_mine look the same for unauthenticated users, while a logged in user sees her books in a bold font on the latter path. The path /my_module/all-books/mine is not accessible at all for unauthenticated users. If you try to access it without being authenticated, you'll be redirected to the login screen in order to do so.

How it works…

The difference between authentication methods is basically what you can expect from the content of request.env.user.

For auth='none', the user record is always empty, even if an authenticated user is accessing the path. Use this if you want to serve content that has no dependencies on users, or if you want to provide database agnostic functionality in a server wide module.

The value auth='public' sets the user record to a special user with XML ID base.public_user, for unauthenticated users, and to the user's record for authenticated ones. This is the right choice if you want to offer functionality to both unauthenticated and authenticated users, while the authenticated ones get some extras, as demonstrated in the preceding code.

Use auth='user' to be sure that only authenticated users have access to what you've got to offer. With this method, you can be sure request.env.user points to some existing user.

There's more…

The magic for authentication methods happens in the ir.http model from the base addon. For whatever value you pass to the auth parameter in your route, Odoo searches for a function called _auth_method_<yourvalue> on this model, so you can easily customize this by inheriting this model and declaring a method that takes care of your authentication method of choice.

As an example, we provide an authentication method base_group_user which enforces a currently logged in user who is a member of the group with XML ID base.group_user:

from openerp import exceptions, http, models
from openerp.http import request

class IrHttp(models.Model):
  _inherit = 'ir.http'

  def _auth_method_base_group_user(self):
    self._auth_method_user()
    if not request.env.user.has_group('base.group_user'):
      raise exceptions.AccessDenied()

Now you can say auth='base_group_user' in your decorator and be sure that users running this route's handler are members of this group. With a little trickery you can extend this to auth='groups(xmlid1,…)', the implementation of this is left as an exercise to the reader, but is included in the example code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.33.235