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

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

parent 29ff14e288ef
No related branches found
No related tags found
No related merge requests found
# -*- encoding: utf-8 -*-
import logging
import lasso
......@@ -20,10 +21,6 @@
'SAML 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 = [
......@@ -53,6 +50,4 @@
raise Exception('Invalid assertion')
# TODO use a real token validation from LASSO
validation = {}
# TODO push into the validation result a real UPN
......@@ -58,5 +53,5 @@
# 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:
......@@ -80,6 +75,7 @@
This method can be overridden to add alternative signin methods.
"""
token_osv = self.pool.get('auth_saml.token')
saml_uid = validation['user_id']
user_ids = self.search(
......@@ -97,4 +93,5 @@
# production code...
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)
......@@ -100,9 +97,31 @@
user = self.browse(cr, uid, user_ids[0], context=context)
# WARNING: writing this means you can only log-in once with a single
# user...
# TODO add a new table with access tokens linked to users
# in order to be able to log multiple times with the same user
user.write({'saml_access_token': saml_response})
user_id = user.id
# now find if a token for this user/provider already exists
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
......@@ -125,10 +144,10 @@
raise openerp.exceptions.AccessDenied()
# return user credentials
return (cr.dbname, login, saml_response)
return cr.dbname, login, saml_response
def check_credentials(self, cr, uid, token):
"""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
and the interesting code is inside the except clause
"""
......@@ -129,7 +148,8 @@
def check_credentials(self, cr, uid, token):
"""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
and the interesting code is inside the except clause
"""
token_osv = self.pool.get('auth_saml.token')
try:
......@@ -135,4 +155,4 @@
try:
return super(res_users, self).check_credentials(cr, uid, token)
super(res_users, self).check_credentials(cr, uid, token)
except openerp.exceptions.AccessDenied:
......@@ -137,5 +157,7 @@
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,
[
......@@ -140,7 +162,7 @@
cr, SUPERUSER_ID,
[
('id', '=', uid),
('user_id', '=', uid),
('saml_access_token', '=', token),
]
)
......@@ -143,6 +165,7 @@
('saml_access_token', '=', token),
]
)
# if the user is not found we re-raise the AccessDenied
if not res:
# TODO: maybe raise a defined exception instead of the last
......@@ -147,4 +170,4 @@
if not res:
# 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
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