Browse Source

[openid_connect] OAuth2 Password Flow

v12_initial_fix
Maciej Wawro 6 years ago
parent
commit
0e27589f65
  1. 2
      galicea_openid_connect/__manifest__.py
  2. 44
      galicea_openid_connect/controllers/main.py
  3. 4
      galicea_openid_connect/models/client.py
  4. 1
      galicea_openid_connect/views/views.xml

2
galicea_openid_connect/__manifest__.py

@ -9,7 +9,7 @@
'website': "http://galicea.pl", 'website': "http://galicea.pl",
'category': 'Technical Settings', 'category': 'Technical Settings',
'version': '10.0.1.0',
'version': '10.0.1.1',
'depends': ['web', 'galicea_environment_checkup'], 'depends': ['web', 'galicea_environment_checkup'],

44
galicea_openid_connect/controllers/main.py

@ -114,7 +114,7 @@ class Main(http.Controller):
'jwks_uri': base_url + 'oauth/jwks', 'jwks_uri': base_url + 'oauth/jwks',
'scopes_supported': ['openid'], 'scopes_supported': ['openid'],
'response_types_supported': RESPONSE_TYPES_SUPPORTED, 'response_types_supported': RESPONSE_TYPES_SUPPORTED,
'grant_types_supported': ['authorization_code', 'implicit'],
'grant_types_supported': ['authorization_code', 'implicit', 'password', 'client_credentials'],
'subject_types_supported': ['public'], 'subject_types_supported': ['public'],
'id_token_signing_alg_values_supported': ['RS256'], 'id_token_signing_alg_values_supported': ['RS256'],
'token_endpoint_auth_methods_supported': ['client_secret_post'] 'token_endpoint_auth_methods_supported': ['client_secret_post']
@ -258,6 +258,8 @@ class Main(http.Controller):
return json.dumps(self.__handle_grant_type_authorization_code(req, **query)) return json.dumps(self.__handle_grant_type_authorization_code(req, **query))
elif query['grant_type'] == 'client_credentials': elif query['grant_type'] == 'client_credentials':
return json.dumps(self.__handle_grant_type_client_credentials(req, **query)) return json.dumps(self.__handle_grant_type_client_credentials(req, **query))
elif query['grant_type'] == 'password':
return json.dumps(self.__handle_grant_type_password(req, **query))
else: else:
raise OAuthException( raise OAuthException(
'Unsupported grant_type param: \'{}\''.format(query['grant_type']), 'Unsupported grant_type param: \'{}\''.format(query['grant_type']),
@ -314,6 +316,46 @@ class Main(http.Controller):
response['id_token'] = self.__create_id_token(req, payload['user_id'], client, extra_claims) response['id_token'] = self.__create_id_token(req, payload['user_id'], client, extra_claims)
return response return response
def __handle_grant_type_password(self, req, **query):
client = self.__validate_client(req, **query)
if not client.allow_password_grant:
raise OAuthException(
'This client is not allowed to perform password flow',
OAuthException.UNSUPPORTED_GRANT_TYPE
)
for param in ['username', 'password']:
if param not in query:
raise OAuthException(
'{} is required'.format(param),
OAuthException.INVALID_REQUEST
)
user_id = req.env['res.users'].authenticate(
req.env.cr.dbname,
query['username'],
query['password'],
None
)
if not user_id:
raise OAuthException(
'Invalid username or password',
OAuthException.INVALID_REQUEST
)
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(
user_id,
client.id
)
response = {
'access_token': token.token,
'token_type': 'bearer'
}
if 'openid' in scopes:
response['id_token'] = self.__create_id_token(req, user_id, client, {})
return response
def __handle_grant_type_client_credentials(self, req, **query): def __handle_grant_type_client_credentials(self, req, **query):
client = self.__validate_client(req, **query) client = self.__validate_client(req, **query)
self.__validate_client_secret(client, req, **query) self.__validate_client_secret(client, req, **query)

4
galicea_openid_connect/models/client.py

@ -30,6 +30,10 @@ class Client(models.Model):
required=True, required=True,
ondelete='restrict' ondelete='restrict'
) )
allow_password_grant = fields.Boolean(
string='Allow OAuth2 password grant',
default=False,
)
@api.model @api.model
def __system_user_name(self, client_name): def __system_user_name(self, client_name):

1
galicea_openid_connect/views/views.xml

@ -27,6 +27,7 @@
<label for="secret" class="oe_read_only" string="Client Secret" /> <label for="secret" class="oe_read_only" string="Client Secret" />
<button class="oe_read_only" string="Show" type="action" name="%(client_action_secret)d" /> <button class="oe_read_only" string="Show" type="action" name="%(client_action_secret)d" />
<field name="auth_redirect_uri" /> <field name="auth_redirect_uri" />
<field name="allow_password_grant" />
</group> </group>
</form> </form>
</field> </field>

Loading…
Cancel
Save