Пример #1
0
    def test_required_roles(self):
        """
        Validates whether the required_roles decorator works
        """
        from api.backend.decorators import required_roles

        @required_roles(['read', 'write', 'manage'])
        def the_function_rr(input_value, *args, **kwargs):
            """
            Decorated function
            """
            _ = args, kwargs
            output['value'] = input_value
            return HttpResponse(json.dumps(input_value))

        time.sleep(180)
        output = {'value': None}
        request = self.factory.get('/')
        with self.assertRaises(HttpUnauthorizedException) as context:
            the_function_rr(1, request)
        self.assertEqual(context.exception.status_code, 401)

        time.sleep(180)
        request.client = type('Client', (), {})
        request.user = type('User', (), {})
        request.user.username = '******'
        with self.assertRaises(HttpUnauthorizedException) as context:
            the_function_rr(2, request)
        self.assertEqual(context.exception.status_code, 401)

        time.sleep(180)
        user = UserList.get_user_by_username('user')
        access_token, _ = OAuth2Toolbox.generate_tokens(
            user.clients[0],
            generate_access=True,
            scopes=RoleList.get_roles_by_codes(['read']))
        access_token.expiration = int(time.time() + 86400)
        access_token.save()
        request.user.username = '******'
        request.token = access_token
        with self.assertRaises(HttpForbiddenException) as context:
            the_function_rr(3, request)
        self.assertEqual(context.exception.status_code, 403)
        self.assertEqual(context.exception.error, 'invalid_roles')
        self.assertEqual(context.exception.error_description,
                         'This call requires roles: read, write, manage')

        time.sleep(180)
        user = UserList.get_user_by_username('admin')
        access_token, _ = OAuth2Toolbox.generate_tokens(
            user.clients[0],
            generate_access=True,
            scopes=RoleList.get_roles_by_codes(['read', 'write', 'manage']))
        access_token.expiration = int(time.time() + 86400)
        access_token.save()
        request.username = '******'
        request.token = access_token
        response = the_function_rr(4, request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, '4')
Пример #2
0
    def test_client_credentials(self):
        """
        Validates the Client Credentials
        """
        from api.oauth2.tokenview import OAuth2TokenView

        time.sleep(180)
        data = {'grant_type': 'client_credentials'}
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.1')
        self._assert_failure(OAuth2TokenView.as_view(), request, 400, 'missing_header', HttpBadRequestException)

        time.sleep(180)
        header = 'Basic {0}'.format(base64.encodestring('{0}:{1}'.format('foo', 'bar')))
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.2', HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400, 'invalid_client', HttpBadRequestException)

        time.sleep(180)
        admin_na = UserList.get_user_by_username('admin_na')
        admin_na_client = Client()
        admin_na_client.ovs_type = 'USER'
        admin_na_client.grant_type = 'PASSWORD'
        admin_na_client.client_secret = OAuth2Toolbox.create_hash(64)
        admin_na_client.user = admin_na
        admin_na_client.save()
        header = 'Basic {0}'.format(base64.encodestring('{0}:{1}'.format(admin_na_client.guid, admin_na_client.client_secret)))
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.3', HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400, 'invalid_grant', HttpBadRequestException)

        time.sleep(180)
        admin_na_client.grant_type = 'CLIENT_CREDENTIALS'
        admin_na_client.save()
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.4', HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400, 'inactive_user', HttpBadRequestException)

        time.sleep(180)
        admin = UserList.get_user_by_username('admin')
        admin_client = Client()
        admin_client.ovs_type = 'USER'
        admin_client.grant_type = 'CLIENT_CREDENTIALS'
        admin_client.client_secret = OAuth2Toolbox.create_hash(64)
        admin_client.user = admin
        admin_client.save()
        header = 'Basic {0}'.format(base64.encodestring('{0}:foobar'.format(admin_client.guid)))
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.5', HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400, 'invalid_client', HttpBadRequestException)

        time.sleep(180)
        header = 'Basic {0}'.format(base64.encodestring('{0}:{1}'.format(admin_client.guid, admin_client.client_secret)))
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.6', HTTP_AUTHORIZATION=header)
        response = OAuth2TokenView.as_view()(request)
        self.assertEqual(response.status_code, 200)
        response_content = json.loads(response.content)
        self.assertIn('access_token', response_content)
        result = {'access_token': response_content['access_token'],
                  'token_type': 'bearer',
                  'expires_in': 3600}
        self.assertDictEqual(response_content, result)
Пример #3
0
    def test_required_roles(self):
        """
        Validates whether the required_roles decorator works
        """
        from api.backend.decorators import required_roles

        @required_roles(['read', 'write', 'manage'])
        def the_function_rr(input_value, *args, **kwargs):
            """
            Decorated function
            """
            _ = args, kwargs
            output['value'] = input_value
            return HttpResponse(json.dumps(input_value))

        time.sleep(180)
        output = {'value': None}
        request = self.factory.get('/')
        with self.assertRaises(HttpUnauthorizedException) as context:
            the_function_rr(1, request)
        self.assertEqual(context.exception.status_code, 401)

        time.sleep(180)
        request.client = type('Client', (), {})
        request.user = type('User', (), {})
        request.user.username = '******'
        with self.assertRaises(HttpUnauthorizedException) as context:
            the_function_rr(2, request)
        self.assertEqual(context.exception.status_code, 401)

        time.sleep(180)
        user = UserList.get_user_by_username('user')
        access_token, _ = OAuth2Toolbox.generate_tokens(user.clients[0], generate_access=True, scopes=RoleList.get_roles_by_codes(['read']))
        access_token.expiration = int(time.time() + 86400)
        access_token.save()
        request.user.username = '******'
        request.token = access_token
        with self.assertRaises(HttpForbiddenException) as context:
            the_function_rr(3, request)
        self.assertEqual(context.exception.status_code, 403)
        self.assertEqual(context.exception.error, 'invalid_roles')
        self.assertEqual(context.exception.error_description, 'This call requires roles: read, write, manage')

        time.sleep(180)
        user = UserList.get_user_by_username('admin')
        access_token, _ = OAuth2Toolbox.generate_tokens(user.clients[0], generate_access=True, scopes=RoleList.get_roles_by_codes(['read', 'write', 'manage']))
        access_token.expiration = int(time.time() + 86400)
        access_token.save()
        request.username = '******'
        request.token = access_token
        response = the_function_rr(4, request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, '4')
Пример #4
0
 def create(self, request, role_guids=None):
     """
     Creates a Client
     :param request: Raw request
     :type request: Request
     :param role_guids: The GUIDs of the roles where the client should get access to
     :type role_guids: str
     """
     if 'role_guids' in request.DATA:
         del request.DATA['role_guids']
     serializer = FullSerializer(Client, instance=Client(), data=request.DATA)
     client = serializer.deserialize()
     if client.user is not None:
         if client.user_guid == request.client.user_guid or Toolbox.is_client_in_roles(request.client, ['manage']):
             client.grant_type = 'CLIENT_CREDENTIALS'
             client.client_secret = OAuth2Toolbox.create_hash(64)
             client.save()
             if not role_guids:
                 roles = [junction.role for junction in client.user.group.roles]
             else:
                 possible_role_guids = [junction.role_guid for junction in client.user.group.roles]
                 roles = [Role(guid) for guid in role_guids if guid in possible_role_guids]
             for role in roles:
                 roleclient = RoleClient()
                 roleclient.client = client
                 roleclient.role = role
                 roleclient.save()
             return client
     raise HttpNotAcceptableException(error_description='A client must have a user',
                                      error='invalid_data')
Пример #5
0
 def create(self, request, role_guids=None):
     """
     Creates a Client
     :param request: Raw request
     :type request: Request
     :param role_guids: The GUIDs of the roles where the client should get access to
     :type role_guids: str
     """
     if 'role_guids' in request.DATA:
         del request.DATA['role_guids']
     serializer = FullSerializer(Client,
                                 instance=Client(),
                                 data=request.DATA)
     client = serializer.deserialize()
     if client.user is not None:
         if client.user_guid == request.client.user_guid or Toolbox.is_client_in_roles(
                 request.client, ['manage']):
             client.grant_type = 'CLIENT_CREDENTIALS'
             client.client_secret = OAuth2Toolbox.create_hash(64)
             client.save()
             if not role_guids:
                 roles = [
                     junction.role for junction in client.user.group.roles
                 ]
             else:
                 possible_role_guids = [
                     junction.role_guid
                     for junction in client.user.group.roles
                 ]
                 roles = [
                     Role(guid) for guid in role_guids
                     if guid in possible_role_guids
                 ]
             for role in roles:
                 roleclient = RoleClient()
                 roleclient.client = client
                 roleclient.role = role
                 roleclient.save()
             return client
     raise HttpNotAcceptableException(
         error_description='A client must have a user',
         error='invalid_data')
Пример #6
0
    def test_client_credentials(self):
        """
        Validates the Client Credentials
        """
        from api.oauth2.tokenview import OAuth2TokenView

        time.sleep(180)
        data = {'grant_type': 'client_credentials'}
        request = self.factory.post('/', data=data, HTTP_X_REAL_IP='127.0.0.1')
        self._assert_failure(OAuth2TokenView.as_view(), request, 400,
                             'missing_header', HttpBadRequestException)

        time.sleep(180)
        header = 'Basic {0}'.format(
            base64.encodestring('{0}:{1}'.format('foo', 'bar')))
        request = self.factory.post('/',
                                    data=data,
                                    HTTP_X_REAL_IP='127.0.0.2',
                                    HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400,
                             'invalid_client', HttpBadRequestException)

        time.sleep(180)
        admin_na = UserList.get_user_by_username('admin_na')
        admin_na_client = Client()
        admin_na_client.ovs_type = 'USER'
        admin_na_client.grant_type = 'PASSWORD'
        admin_na_client.client_secret = OAuth2Toolbox.create_hash(64)
        admin_na_client.user = admin_na
        admin_na_client.save()
        header = 'Basic {0}'.format(
            base64.encodestring('{0}:{1}'.format(
                admin_na_client.guid, admin_na_client.client_secret)))
        request = self.factory.post('/',
                                    data=data,
                                    HTTP_X_REAL_IP='127.0.0.3',
                                    HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400,
                             'invalid_grant', HttpBadRequestException)

        time.sleep(180)
        admin_na_client.grant_type = 'CLIENT_CREDENTIALS'
        admin_na_client.save()
        request = self.factory.post('/',
                                    data=data,
                                    HTTP_X_REAL_IP='127.0.0.4',
                                    HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400,
                             'inactive_user', HttpBadRequestException)

        time.sleep(180)
        admin = UserList.get_user_by_username('admin')
        admin_client = Client()
        admin_client.ovs_type = 'USER'
        admin_client.grant_type = 'CLIENT_CREDENTIALS'
        admin_client.client_secret = OAuth2Toolbox.create_hash(64)
        admin_client.user = admin
        admin_client.save()
        header = 'Basic {0}'.format(
            base64.encodestring('{0}:foobar'.format(admin_client.guid)))
        request = self.factory.post('/',
                                    data=data,
                                    HTTP_X_REAL_IP='127.0.0.5',
                                    HTTP_AUTHORIZATION=header)
        self._assert_failure(OAuth2TokenView.as_view(), request, 400,
                             'invalid_client', HttpBadRequestException)

        time.sleep(180)
        header = 'Basic {0}'.format(
            base64.encodestring('{0}:{1}'.format(admin_client.guid,
                                                 admin_client.client_secret)))
        request = self.factory.post('/',
                                    data=data,
                                    HTTP_X_REAL_IP='127.0.0.6',
                                    HTTP_AUTHORIZATION=header)
        response = OAuth2TokenView.as_view()(request)
        self.assertEqual(response.status_code, 200)
        response_content = json.loads(response.content)
        self.assertIn('access_token', response_content)
        result = {
            'access_token': response_content['access_token'],
            'token_type': 'bearer',
            'expires_in': 3600
        }
        self.assertDictEqual(response_content, result)
Пример #7
0
    def get(self, request, *args, **kwargs):
        """
        Handles token post
        """
        _ = args, kwargs
        html_endpoint = Configuration.get(
            '/ovs/framework/webapps|html_endpoint')
        if 'code' not in request.GET:
            OAuth2RedirectView._logger.error(
                'Got OAuth2 redirection request without code')
            return HttpResponseRedirect(html_endpoint)
        code = request.GET['code']
        if 'state' not in request.GET:
            OAuth2RedirectView._logger.error(
                'Got OAuth2 redirection request without state')
            return HttpResponseRedirect(html_endpoint)
        state = request.GET['state']
        if 'error' in request.GET:
            error = request.GET['error']
            description = request.GET[
                'error_description'] if 'error_description' in request.GET else ''
            OAuth2RedirectView._logger.error(
                'Error {0} during OAuth2 redirection request: {1}'.format(
                    error, description))
            return HttpResponseRedirect(html_endpoint)

        base_url = Configuration.get('/ovs/framework/webapps|oauth2.token_uri')
        client_id = Configuration.get(
            '/ovs/framework/webapps|oauth2.client_id')
        client_secret = Configuration.get(
            '/ovs/framework/webapps|oauth2.client_secret')
        parameters = {
            'grant_type':
            'authorization_code',
            'redirect_url':
            'https://{0}/api/oauth2/redirect/'.format(
                System.get_my_storagerouter().ip),
            'client_id':
            client_id,
            'code':
            code
        }
        url = '{0}?{1}'.format(base_url, urllib.urlencode(parameters))
        headers = {
            'Accept':
            'application/json',
            'Authorization':
            'Basic {0}'.format(
                base64.b64encode('{0}:{1}'.format(client_id,
                                                  client_secret)).strip())
        }
        raw_response = requests.post(url=url, headers=headers, verify=False)
        response = raw_response.json()
        if 'error' in response:
            error = response['error']
            description = response[
                'error_description'] if 'error_description' in response else ''
            OAuth2RedirectView._logger.error(
                'Error {0} during OAuth2 redirection access token: {1}'.format(
                    error, description))
            return HttpResponseRedirect(html_endpoint)

        token = response['access_token']
        expires_in = response['expires_in']

        clients = ClientList.get_by_types('INTERNAL', 'CLIENT_CREDENTIALS')
        client = None
        for current_client in clients:
            if current_client.user.group.name == 'administrators':
                client = current_client
                break
        if client is None:
            OAuth2RedirectView._logger.error(
                'Could not find INTERNAL CLIENT_CREDENTIALS client in administrator group.'
            )
            return HttpResponseRedirect(html_endpoint)

        roles = RoleList.get_roles_by_codes(['read', 'write', 'manage'])
        access_token, _ = Toolbox.generate_tokens(client,
                                                  generate_access=True,
                                                  scopes=roles)
        access_token.expiration = int(time.time() + expires_in)
        access_token.access_token = token
        access_token.save()

        expires = datetime.datetime.now() + datetime.timedelta(minutes=2)
        response = HttpResponseRedirect(html_endpoint)
        response.set_cookie('state', state, expires=expires, secure=True)
        response.set_cookie('accesstoken', token, expires=expires, secure=True)

        return response
Пример #8
0
 def post(self, request, *args, **kwargs):
     """
     Handles token post
     """
     logger = LogHandler.get('api', 'oauth2')
     _ = args, kwargs
     if 'grant_type' not in request.POST:
         raise HttpBadRequestException(
             error='invalid_request',
             error_description='No grant type specified')
     grant_type = request.POST['grant_type']
     scopes = None
     if 'scope' in request.POST:
         scopes = RoleList.get_roles_by_codes(
             request.POST['scope'].split(' '))
     if grant_type == 'password':
         # Resource Owner Password Credentials Grant
         if 'username' not in request.POST or 'password' not in request.POST:
             raise HttpBadRequestException(
                 error='invalid_request',
                 error_description='Invalid request')
         username = request.POST['username']
         password = request.POST['password']
         user = UserList.get_user_by_username(username)
         if user is None or user.password != hashlib.sha256(
                 password).hexdigest():
             raise HttpBadRequestException(
                 error='invalid_client', error_description='Invalid client')
         if user.is_active is False:
             raise HttpBadRequestException(
                 error='inactive_user',
                 error_description='User is inactive')
         clients = [
             client for client in user.clients
             if client.ovs_type == 'INTERNAL'
             and client.grant_type == 'PASSWORD'
         ]
         if len(clients) != 1:
             raise HttpBadRequestException(
                 error='unauthorized_client',
                 error_description='Client is unautorized')
         client = clients[0]
         try:
             access_token, _ = Toolbox.generate_tokens(client,
                                                       generate_access=True,
                                                       scopes=scopes)
             access_token.expiration = int(time.time() + 86400)
             access_token.save()
         except ValueError as error:
             if error.message == 'invalid_scope':
                 raise HttpBadRequestException(
                     error='invalid_scope',
                     error_description='Invalid scope requested')
             raise
         Toolbox.clean_tokens(client)
         return HttpResponse(json.dumps({
             'access_token': access_token.access_token,
             'token_type': 'bearer',
             'expires_in': 86400
         }),
                             content_type='application/json')
     elif grant_type == 'client_credentials':
         # Client Credentials
         if 'HTTP_AUTHORIZATION' not in request.META:
             raise HttpBadRequestException(
                 error='missing_header',
                 error_description='Authorization header missing')
         _, password_hash = request.META['HTTP_AUTHORIZATION'].split(' ')
         client_id, client_secret = base64.b64decode(password_hash).split(
             ':', 1)
         try:
             client = Client(client_id)
             if client.grant_type != 'CLIENT_CREDENTIALS':
                 raise HttpBadRequestException(
                     error='invalid_grant',
                     error_description=
                     'The given grant type is not supported')
             if client.client_secret != client_secret:
                 raise HttpBadRequestException(
                     error='invalid_client',
                     error_description='Invalid client')
             if not client.user.is_active:
                 raise HttpBadRequestException(
                     error='inactive_user',
                     error_description='User is inactive')
             try:
                 access_token, _ = Toolbox.generate_tokens(
                     client, generate_access=True, scopes=scopes)
             except ValueError as error:
                 if error.message == 'invalid_scope':
                     raise HttpBadRequestException(
                         error='invalid_scope',
                         error_description='Invalid scope requested')
                 raise
             try:
                 Toolbox.clean_tokens(client)
             except Exception as error:
                 logger.error(
                     'Error during session cleanup: {0}'.format(error))
             return HttpResponse(json.dumps({
                 'access_token': access_token.access_token,
                 'token_type': 'bearer',
                 'expires_in': 3600
             }),
                                 content_type='application/json')
         except HttpBadRequestException:
             raise
         except ObjectNotFoundException as ex:
             logger.warning('Error matching client: {0}'.format(ex))
             raise HttpBadRequestException(
                 error='invalid_client',
                 error_description='Client could not be found')
         except Exception as ex:
             logger.exception('Error matching client: {0}'.format(ex))
             raise HttpBadRequestException(
                 error='invalid_client',
                 error_description='Error loading client')
     else:
         raise HttpBadRequestException(
             error='unsupported_grant_type',
             error_description='Unsupported grant type')
Пример #9
0
    def get(self, request, *args, **kwargs):
        """
        Handles token post
        """
        _ = args, kwargs
        html_endpoint = Configuration.get('/ovs/framework/webapps|html_endpoint')
        if 'code' not in request.GET:
            OAuth2RedirectView._logger.error('Got OAuth2 redirection request without code')
            return HttpResponseRedirect(html_endpoint)
        code = request.GET['code']
        if 'state' not in request.GET:
            OAuth2RedirectView._logger.error('Got OAuth2 redirection request without state')
            return HttpResponseRedirect(html_endpoint)
        state = request.GET['state']
        if 'error' in request.GET:
            error = request.GET['error']
            description = request.GET['error_description'] if 'error_description' in request.GET else ''
            OAuth2RedirectView._logger.error('Error {0} during OAuth2 redirection request: {1}'.format(error, description))
            return HttpResponseRedirect(html_endpoint)

        base_url = Configuration.get('/ovs/framework/webapps|oauth2.token_uri')
        client_id = Configuration.get('/ovs/framework/webapps|oauth2.client_id')
        client_secret = Configuration.get('/ovs/framework/webapps|oauth2.client_secret')
        parameters = {'grant_type': 'authorization_code',
                      'redirect_url': 'https://{0}/api/oauth2/redirect/'.format(System.get_my_storagerouter().ip),
                      'client_id': client_id,
                      'code': code}
        url = '{0}?{1}'.format(base_url, urllib.urlencode(parameters))
        headers = {'Accept': 'application/json',
                   'Authorization': 'Basic {0}'.format(base64.b64encode('{0}:{1}'.format(client_id, client_secret)).strip())}
        raw_response = requests.post(url=url, headers=headers, verify=False)
        response = raw_response.json()
        if 'error' in response:
            error = response['error']
            description = response['error_description'] if 'error_description' in response else ''
            OAuth2RedirectView._logger.error('Error {0} during OAuth2 redirection access token: {1}'.format(error, description))
            return HttpResponseRedirect(html_endpoint)

        token = response['access_token']
        expires_in = response['expires_in']

        clients = ClientList.get_by_types('INTERNAL', 'CLIENT_CREDENTIALS')
        client = None
        for current_client in clients:
            if current_client.user.group.name == 'administrators':
                client = current_client
                break
        if client is None:
            OAuth2RedirectView._logger.error('Could not find INTERNAL CLIENT_CREDENTIALS client in administrator group.')
            return HttpResponseRedirect(html_endpoint)

        roles = RoleList.get_roles_by_codes(['read', 'write', 'manage'])
        access_token, _ = Toolbox.generate_tokens(client, generate_access=True, scopes=roles)
        access_token.expiration = int(time.time() + expires_in)
        access_token.access_token = token
        access_token.save()

        expires = datetime.datetime.now() + datetime.timedelta(minutes=2)
        response = HttpResponseRedirect(html_endpoint)
        response.set_cookie('state', state, expires=expires, secure=True)
        response.set_cookie('accesstoken', token, expires=expires, secure=True)

        return response
Пример #10
0
 def post(self, request, *args, **kwargs):
     """
     Handles token post
     """
     logger = LogHandler.get('api', 'oauth2')
     _ = args, kwargs
     if 'grant_type' not in request.POST:
         raise HttpBadRequestException(error='invalid_request',
                                       error_description='No grant type specified')
     grant_type = request.POST['grant_type']
     scopes = None
     if 'scope' in request.POST:
         scopes = RoleList.get_roles_by_codes(request.POST['scope'].split(' '))
     if grant_type == 'password':
         # Resource Owner Password Credentials Grant
         if 'username' not in request.POST or 'password' not in request.POST:
             raise HttpBadRequestException(error='invalid_request',
                                           error_description='Invalid request')
         username = request.POST['username']
         password = request.POST['password']
         user = UserList.get_user_by_username(username)
         if user is None or user.password != hashlib.sha256(password).hexdigest():
             raise HttpBadRequestException(error='invalid_client',
                                           error_description='Invalid client')
         if user.is_active is False:
             raise HttpBadRequestException(error='inactive_user',
                                           error_description='User is inactive')
         clients = [client for client in user.clients if client.ovs_type == 'INTERNAL' and client.grant_type == 'PASSWORD']
         if len(clients) != 1:
             raise HttpBadRequestException(error='unauthorized_client',
                                           error_description='Client is unautorized')
         client = clients[0]
         try:
             access_token, _ = Toolbox.generate_tokens(client, generate_access=True, scopes=scopes)
             access_token.expiration = int(time.time() + 86400)
             access_token.save()
         except ValueError as error:
             if error.message == 'invalid_scope':
                 raise HttpBadRequestException(error='invalid_scope',
                                               error_description='Invalid scope requested')
             raise
         Toolbox.clean_tokens(client)
         return HttpResponse(json.dumps({'access_token': access_token.access_token,
                                         'token_type': 'bearer',
                                         'expires_in': 86400}),
                             content_type='application/json')
     elif grant_type == 'client_credentials':
         # Client Credentials
         if 'HTTP_AUTHORIZATION' not in request.META:
             raise HttpBadRequestException(error='missing_header',
                                           error_description='Authorization header missing')
         _, password_hash = request.META['HTTP_AUTHORIZATION'].split(' ')
         client_id, client_secret = base64.b64decode(password_hash).split(':', 1)
         try:
             client = Client(client_id)
             if client.grant_type != 'CLIENT_CREDENTIALS':
                 raise HttpBadRequestException(error='invalid_grant',
                                               error_description='The given grant type is not supported')
             if client.client_secret != client_secret:
                 raise HttpBadRequestException(error='invalid_client',
                                               error_description='Invalid client')
             if not client.user.is_active:
                 raise HttpBadRequestException(error='inactive_user',
                                               error_description='User is inactive')
             try:
                 access_token, _ = Toolbox.generate_tokens(client, generate_access=True, scopes=scopes)
             except ValueError as error:
                 if error.message == 'invalid_scope':
                     raise HttpBadRequestException(error='invalid_scope',
                                                   error_description='Invalid scope requested')
                 raise
             try:
                 Toolbox.clean_tokens(client)
             except Exception as error:
                 logger.error('Error during session cleanup: {0}'.format(error))
             return HttpResponse(json.dumps({'access_token': access_token.access_token,
                                             'token_type': 'bearer',
                                             'expires_in': 3600}),
                                 content_type='application/json')
         except HttpBadRequestException:
             raise
         except ObjectNotFoundException as ex:
             logger.warning('Error matching client: {0}'.format(ex))
             raise HttpBadRequestException(error='invalid_client',
                                           error_description='Client could not be found')
         except Exception as ex:
             logger.exception('Error matching client: {0}'.format(ex))
             raise HttpBadRequestException(error='invalid_client',
                                           error_description='Error loading client')
     else:
         raise HttpBadRequestException(error='unsupported_grant_type',
                                       error_description='Unsupported grant type')