Esempio n. 1
0
File: views.py Progetto: calonx/dach
def install(request):
    if request.method == 'POST':
        app_name = request.resolver_match.app_name
        if not app_name:
            raise Exception('you must include the dach.urls with the app_name')
        appconfig = DACH_CONFIG['appconfig']
        scopes_list = appconfig[app_name]['scopes']

        info = json.loads(force_text(request.body))
        capabilities_url = lookup_dict(info, 'capabilitiesUrl')
        token_url, api_url = _get_and_check_capabilities(capabilities_url)
        tenant = Tenant()
        tenant.oauth_id = info['oauthId']
        tenant.oauth_secret = info['oauthSecret']
        tenant.capabilities_url = capabilities_url
        tenant.oauth_token_url = token_url
        tenant.api_url = api_url
        tenant.group_id = info['groupId']
        tenant.room_id = info.get('roomId', None)
        tenant.app_name = app_name
        tenant.scopes = '|'.join(scopes_list)

        token = get_access_token(tenant)

        tenant.group_name = token.group_name
        get_backend().set(tenant.oauth_id, 'tenant', tenant.json())
        post_install.send(apps.get_app_config(app_name), tenant=tenant)
        logger.info('addon successfully installed')
        return HttpResponse(status=204)
    return HttpResponseNotAllowed(['post'])
Esempio n. 2
0
File: views.py Progetto: calonx/dach
def uninstall(request, oauth_id):
    if request.method == 'DELETE':
        app_name = request.resolver_match.app_name
        if not app_name:
            raise Exception('you must include the dach.urls with the app_name')
        get_backend().delete(oauth_id)
        post_uninstall.send(apps.get_app_config(app_name), oauth_id=oauth_id)
        logger.info('addon successfully uninstalled')
        return HttpResponse(status=204)
    return HttpResponseNotAllowed(['delete'])
Esempio n. 3
0
File: auth.py Progetto: calonx/dach
def get_access_token(tenant):

    def _generate_token():
        logger.debug('generate access token at %s for %s',
                     tenant.oauth_token_url, tenant.oauth_id)
        payload = {
            'grant_type': 'client_credentials',
            'scope': ' '.join(tenant.scopes.split('|'))
        }
        res = requests.post(
            tenant.oauth_token_url,
            data=payload,
            auth=(tenant.oauth_id, tenant.oauth_secret)
        )
        if res.status_code == 200:
            token_info = res.json()
            token = Token(oauth_id=tenant.oauth_id, **token_info)
            token.created = time.time()
            token.scope = '|'.join(token.scope.split(' '))
            get_backend().set(tenant.oauth_id, 'token', token.json())
            return token
        raise Exception('cannot generate access token: %s', res.status_code)

    token = get_backend().get(tenant.oauth_id, 'token')
    if token:
        logger.debug('token exists for %s', tenant.oauth_id)
        created = datetime.fromtimestamp(float(token.created))
        expires = created + timedelta(seconds=token.expires_in)
        if expires < datetime.now():
            logger.debug('token expired for %s', tenant.oauth_id)
            return _generate_token()
        logger.debug('token is yet valid for %s', tenant.oauth_id)
        return token
    logger.debug('no token found for %s', tenant.oauth_id)
    return _generate_token()
Esempio n. 4
0
File: auth.py Progetto: calonx/dach
 def _generate_token():
     logger.debug('generate access token at %s for %s',
                  tenant.oauth_token_url, tenant.oauth_id)
     payload = {
         'grant_type': 'client_credentials',
         'scope': ' '.join(tenant.scopes.split('|'))
     }
     res = requests.post(
         tenant.oauth_token_url,
         data=payload,
         auth=(tenant.oauth_id, tenant.oauth_secret)
     )
     if res.status_code == 200:
         token_info = res.json()
         token = Token(oauth_id=tenant.oauth_id, **token_info)
         token.created = time.time()
         token.scope = '|'.join(token.scope.split(' '))
         get_backend().set(tenant.oauth_id, 'token', token.json())
         return token
     raise Exception('cannot generate access token: %s', res.status_code)
Esempio n. 5
0
 def setUp(self):
     tenant_data = {
         'oauth_id': 'my_oauth_id',
         'oauth_secret': 'my_oauth_secret',
         'capabilities_url': 'http://someurl.com/capabilities',
         'group_id': 1,
         'room_id': 2
     }
     token_data = {
         'oauth_id': 'my_oauth_id',
         'access_token': 'my access token',
         'expires_in': 3600,
         'group_name': 'test_group',
         'token_type': 'bearer',
         'scope': 'scope1|scope2',
         'group_id': 1,
         'created': time()
     }
     get_backend().set('my_oauth_id', 'tenant', json.dumps(tenant_data))
     get_backend().set('my_oauth_id', 'token', json.dumps(token_data))
Esempio n. 6
0
 def test_uninstall(self):
     handler = MagicMock()
     post_uninstall.connect(handler)
     tenant_data = {
         'oauth_id': 'my_oauth_id',
         'oauth_secret': 'my_oauth_secret',
         'capabilities_url': 'http://someurl.com/capabilities',
         'group_id': 1,
         'room_id': 2
     }
     token_data = {
         'oauth_id': 'my_oauth_id',
         'access_token': 'my access token',
         'expires_in': 3600,
         'group_name': 'test_group',
         'token_type': 'bearer',
         'scope': 'scope1|scope2',
         'group_id': 1,
         'created': time.time()
     }
     get_backend().set('my_oauth_id', 'tenant', json.dumps(tenant_data))
     get_backend().set('my_oauth_id', 'token', json.dumps(token_data))
     res = self.client.delete(reverse('test:uninstall',
                                      args=['my_oauth_id']))
     self.assertEqual(res.status_code, 204)
     self.assertIsNone(get_backend().get('my_oauth_id', 'tenant'))
     self.assertIsNone(get_backend().get('my_oauth_id', 'token'))
     handler.assert_called_once_with(
         signal=post_uninstall,
         sender=apps.get_app_config('dach'),
         oauth_id='my_oauth_id'
     )
Esempio n. 7
0
    def test_install(self):
        handler = MagicMock()
        post_install.connect(handler)

        def token_request_callback(request):
            auth = request.headers['Authorization']
            auth = force_text(base64.b64decode(auth[6:]))
            auth = auth.split(':')
            payload = six.moves.urllib_parse.parse_qs(request.body)
            self.assertEqual(auth[0], 'my_oauth_id')
            self.assertEqual(auth[1], 'my_oauth_secret')
            self.assertIn('grant_type', payload)
            self.assertIn('scope', payload)
            return (200, {'Content_Type': 'application/json'},
                    json.dumps(token_response))

        post_data = {
            'oauthId': 'my_oauth_id',
            'oauthSecret': 'my_oauth_secret',
            'capabilitiesUrl': 'http://someurl.com/capabilities',
            'groupId': 1,
            'roomId': 2
        }
        capabilities_response = {
            'links': {
                'self': 'http://someurl.com/capabilities',
                'api': 'http://someurl.com/api'
            },
            'capabilities': {
                'oauth2Provider': {
                    'tokenUrl': 'http://someurl.com/token'
                }
            }
        }
        token_response = {
            'access_token': 'my access token',
            'expires_in': 3600,
            'group_name': 'test_group',
            'token_type': 'bearer',
            'scope': 'scope1 scope2',
            'group_id': 1
        }
        responses.add(
            responses.GET,
            'http://someurl.com/capabilities',
            body=json.dumps(capabilities_response),
            content_type='application/json',
            status=200
        )
        responses.add_callback(
            responses.POST,
            'http://someurl.com/token',
            callback=token_request_callback
        )

        response = self.client.post(
            reverse('test:install'),
            data=json.dumps(post_data),
            content_type='application/json'
        )
        self.assertEqual(response.status_code, 204)

        tenant = get_backend().get('my_oauth_id', 'tenant')
        token = get_backend().get('my_oauth_id', 'token')
        self.assertIsNotNone(tenant)
        self.assertIsNotNone(token)
        tenant = Tenant.from_json(tenant)
        token = Token.from_json(token)
        self.assertEqual(tenant.oauth_secret, 'my_oauth_secret')
        self.assertEqual(tenant.group_id, 1)
        self.assertEqual(tenant.group_name, 'test_group')
        self.assertEqual(tenant.room_id, 2)
        self.assertEqual(tenant.capabilities_url,
                         'http://someurl.com/capabilities')
        self.assertEqual(tenant.api_url,
                         'http://someurl.com/api')
        self.assertEqual(tenant.app_name, 'dach')
        self.assertEqual(tenant.scopes, 'scope1|scope2')
        # self.assertEqual(force_text(tenant.capabilities_doc.read()),
        #                  json.dumps(capabilities_response))
        self.assertEqual(token.group_id, 1)
        self.assertEqual(token.group_name, 'test_group')
        self.assertEqual(token.access_token, 'my access token')
        self.assertEqual(token.expires_in, 3600)
        self.assertEqual(token.scope, 'scope1|scope2')
        self.assertEqual(token.token_type, 'bearer')

        handler.assert_called_once_with(
            signal=post_install,
            sender=apps.get_app_config('dach'),
            tenant=tenant
        )