diff --git a/galicea_openid_connect/__manifest__.py b/galicea_openid_connect/__manifest__.py
index bc24662..1cdfcb1 100644
--- a/galicea_openid_connect/__manifest__.py
+++ b/galicea_openid_connect/__manifest__.py
@@ -9,7 +9,7 @@
'website': "http://galicea.pl",
'category': 'Technical Settings',
- 'version': '10.0.1.1',
+ 'version': '10.0.1.2',
'depends': ['web', 'galicea_environment_checkup'],
diff --git a/galicea_openid_connect/api.py b/galicea_openid_connect/api.py
index bf19be2..0de6a39 100644
--- a/galicea_openid_connect/api.py
+++ b/galicea_openid_connect/api.py
@@ -16,7 +16,13 @@ class ApiException(Exception):
super(Exception, self).__init__(message)
self.code = code if code else self.INVALID_REQUEST
-def resource(path, method, auth='user'):
+ def to_json(self):
+ return {
+ 'error': self.code,
+ 'error_message': self.message
+ }
+
+def resource(path, method, auth='user', clients=None):
assert auth in ['user', 'client']
def endpoint_decorator(func):
@@ -68,6 +74,10 @@ def resource(path, method, auth='user'):
)
req.uid = token.client_id.system_user_id.id
+ if clients:
+ if token.client_id.id not in map(lambda c: req.env.ref(c).id, clients):
+ raise ApiException('Access denied', 'restricted_app')
+
ctx = req.context.copy()
ctx.update({'client_id': token.client_id.id})
req.context = ctx
@@ -78,22 +88,17 @@ def resource(path, method, auth='user'):
headers=cors_headers,
status=200
)
- except ApiException as e:
+ except Exception as e:
+ status = 400
+ if not isinstance(e, ApiException):
+ _logger.exception('Unexpected exception while processing API request')
+ e = ApiException('Unexpected server error', 'server_error')
+ status = 500
return werkzeug.Response(
- response=json.dumps({'error': e.code, 'error_message': e.message}),
- status=400,
+ response=json.dumps(e.to_json()),
+ status=status,
headers=cors_headers
)
- except:
- _logger.exception('Unexpected exception while processing API request')
- return werkzeug.Response(
- response=json.dumps({
- 'error': 'server_error',
- 'error_message': 'Unexpected server error',
- }),
- headers=cors_headers,
- status=500
- )
return func_wrapper
return endpoint_decorator
diff --git a/galicea_openid_connect/controllers/main.py b/galicea_openid_connect/controllers/main.py
index 2fafaf2..d5419a3 100644
--- a/galicea_openid_connect/controllers/main.py
+++ b/galicea_openid_connect/controllers/main.py
@@ -47,6 +47,7 @@ class OAuthException(Exception):
UNSUPPORTED_RESPONSE_TYPE = 'unsupported_response_type'
INVALID_GRANT = 'invalid_grant'
UNSUPPORTED_GRANT_TYPE = 'unsupported_grant_type'
+ RESTRICTED_APP = 'restricted_app'
def __init__(self, message, type):
super(Exception, self).__init__(message)
@@ -103,6 +104,15 @@ class Main(http.Controller):
OAuthException.INVALID_CLIENT,
)
+ def __validate_user(self, client, user):
+ if not client.user_group_id:
+ return
+ if client.user_group_id not in user.groups_id:
+ raise OAuthException(
+ 'User is not allowed to use this client',
+ OAuthException.RESTRICTED_APP
+ )
+
@http.route('/.well-known/openid-configuration', auth='public', type='http')
def metadata(self, req, **query):
base_url = http.request.httprequest.host_url
@@ -206,6 +216,7 @@ class Main(http.Controller):
}
return self.__redirect('/web/login', params, 'query')
+ self.__validate_user(client, user)
response_types = response_type.split()
extra_claims = {
@@ -355,7 +366,7 @@ class Main(http.Controller):
'Invalid username or password',
OAuthException.INVALID_REQUEST
)
-
+ self.__validate_user(client, req.env['res.users'].sudo().browse(user_id))
scopes = query['scope'].split(' ') if query.get('scope') else []
# Retrieve/generate access token. We currently only store one per user/client
token = req.env['galicea_openid_connect.access_token'].sudo().retrieve_or_create(
diff --git a/galicea_openid_connect/models/client.py b/galicea_openid_connect/models/client.py
index 0c00e20..70f353e 100644
--- a/galicea_openid_connect/models/client.py
+++ b/galicea_openid_connect/models/client.py
@@ -34,6 +34,10 @@ class Client(models.Model):
string='Allow OAuth2 password grant',
default=False,
)
+ user_group_id = fields.Many2one(
+ 'res.groups',
+ 'Restrict the client to a group'
+ )
@api.model
def __system_user_name(self, client_name):
diff --git a/galicea_openid_connect/views/views.xml b/galicea_openid_connect/views/views.xml
index 6e6cc66..facd3e1 100644
--- a/galicea_openid_connect/views/views.xml
+++ b/galicea_openid_connect/views/views.xml
@@ -28,6 +28,7 @@
+