Skip to content
Snippets Groups Projects
Commit 06ccd421 authored by Florent Aide's avatar Florent Aide
Browse files

Tokens are now in their own table to avoid locks on res.users

parent 29ff14e2
No related branches found
No related tags found
No related merge requests found
# -*- encoding: utf-8 -*-
import logging import logging
import lasso import lasso
...@@ -20,10 +21,6 @@ ...@@ -20,10 +21,6 @@
'SAML User ID', 'SAML User ID',
help="SAML Provider user_id", help="SAML Provider user_id",
), ),
'saml_access_token': fields.char(
'Current SAML token for this user',
help="The current SAML token in use",
),
} }
_sql_constraints = [ _sql_constraints = [
...@@ -53,6 +50,4 @@ ...@@ -53,6 +50,4 @@
raise Exception('Invalid assertion') raise Exception('Invalid assertion')
# TODO use a real token validation from LASSO # TODO use a real token validation from LASSO
validation = {}
# TODO push into the validation result a real UPN # TODO push into the validation result a real UPN
...@@ -58,5 +53,5 @@ ...@@ -58,5 +53,5 @@
# TODO push into the validation result a real UPN # TODO push into the validation result a real UPN
validation['user_id'] = login.assertion.subject.nameId.content validation = {'user_id': login.assertion.subject.nameId.content}
""" """
if p.data_endpoint: if p.data_endpoint:
...@@ -80,6 +75,7 @@ ...@@ -80,6 +75,7 @@
This method can be overridden to add alternative signin methods. This method can be overridden to add alternative signin methods.
""" """
token_osv = self.pool.get('auth_saml.token')
saml_uid = validation['user_id'] saml_uid = validation['user_id']
user_ids = self.search( user_ids = self.search(
...@@ -97,4 +93,5 @@ ...@@ -97,4 +93,5 @@
# production code... # production code...
assert len(user_ids) == 1 assert len(user_ids) == 1
# browse the user because we'll need this in the response
user = self.browse(cr, uid, user_ids[0], context=context) user = self.browse(cr, uid, user_ids[0], context=context)
...@@ -100,9 +97,31 @@ ...@@ -100,9 +97,31 @@
user = self.browse(cr, uid, user_ids[0], context=context) user = self.browse(cr, uid, user_ids[0], context=context)
# WARNING: writing this means you can only log-in once with a single
# user... user_id = user.id
# TODO add a new table with access tokens linked to users
# in order to be able to log multiple times with the same user # now find if a token for this user/provider already exists
user.write({'saml_access_token': saml_response}) token_ids = token_osv.search(
cr, uid,
[
('saml_provider_id', '=', provider),
('user_id', '=', user_id),
]
)
if token_ids:
token_osv.write(
cr, uid, token_ids,
{'saml_access_token': saml_response},
context=context
)
else:
token_osv.create(
cr, uid,
{
'saml_access_token': saml_response,
'saml_provider_id': provider,
'user_id': user_id,
},
context=context
)
return user.login return user.login
...@@ -125,10 +144,10 @@ ...@@ -125,10 +144,10 @@
raise openerp.exceptions.AccessDenied() raise openerp.exceptions.AccessDenied()
# return user credentials # return user credentials
return (cr.dbname, login, saml_response) return cr.dbname, login, saml_response
def check_credentials(self, cr, uid, token): def check_credentials(self, cr, uid, token):
"""token can be a password if the user has used the normal form... """token can be a password if the user has used the normal form...
but we are more interested in the case when they are tokens but we are more interested in the case when they are tokens
and the interesting code is inside the except clause and the interesting code is inside the except clause
""" """
...@@ -129,7 +148,8 @@ ...@@ -129,7 +148,8 @@
def check_credentials(self, cr, uid, token): def check_credentials(self, cr, uid, token):
"""token can be a password if the user has used the normal form... """token can be a password if the user has used the normal form...
but we are more interested in the case when they are tokens but we are more interested in the case when they are tokens
and the interesting code is inside the except clause and the interesting code is inside the except clause
""" """
token_osv = self.pool.get('auth_saml.token')
try: try:
...@@ -135,4 +155,4 @@ ...@@ -135,4 +155,4 @@
try: try:
return super(res_users, self).check_credentials(cr, uid, token) super(res_users, self).check_credentials(cr, uid, token)
except openerp.exceptions.AccessDenied: except openerp.exceptions.AccessDenied:
...@@ -137,5 +157,7 @@ ...@@ -137,5 +157,7 @@
except openerp.exceptions.AccessDenied: except openerp.exceptions.AccessDenied:
res = self.search( # since normal auth did not succeed we now try to find if the user
# has an active token attached to his uid
res = token_osv.search(
cr, SUPERUSER_ID, cr, SUPERUSER_ID,
[ [
...@@ -140,7 +162,7 @@ ...@@ -140,7 +162,7 @@
cr, SUPERUSER_ID, cr, SUPERUSER_ID,
[ [
('id', '=', uid), ('user_id', '=', uid),
('saml_access_token', '=', token), ('saml_access_token', '=', token),
] ]
) )
...@@ -143,6 +165,7 @@ ...@@ -143,6 +165,7 @@
('saml_access_token', '=', token), ('saml_access_token', '=', token),
] ]
) )
# if the user is not found we re-raise the AccessDenied
if not res: if not res:
# TODO: maybe raise a defined exception instead of the last # TODO: maybe raise a defined exception instead of the last
...@@ -147,4 +170,4 @@ ...@@ -147,4 +170,4 @@
if not res: if not res:
# TODO: maybe raise a defined exception instead of the last # TODO: maybe raise a defined exception instead of the last
# exception that occured in our execution frame # exception that occurred in our execution frame
raise raise
token.py 0 → 100644
# -*- encoding: utf-8 -*-
__author__ = 'faide'
import logging
from openerp.osv import osv, fields
_logger = logging.getLogger(__name__)
class saml_token(osv.Model):
_name = "auth_saml.token"
_rec_name = "user_id"
_columns = {
'saml_provider_id': fields.many2one(
'auth.saml.provider',
string='SAML Provider that issued the token',
),
'user_id': fields.many2one(
'res.users',
string="User",
# we want the token to be destroyed if the corresponding res.users
# is deleted
ondelete="cascade"
),
'saml_access_token': fields.char(
'Current SAML token for this user',
help="The current SAML token in use",
),
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment