Example #1
0
def supplement_user(user: User, subscription: Subscription):
    user.user_id = create_user_id_from_email(user.email)

    client_id, client_secret = create_secret()
    user.user_metadata.client_id = subscription.client_id or client_id
    user.user_metadata.client_secret = subscription.client_secret or client_secret
    user.password = util.generate_temp_password()

    return user
Example #2
0
def get_token(body: JsonObject):
    user_client_id = util.maybe_raise_for_env("AUTH0_USER_MANAGEMENT_CLIENT_ID")
    oauth_token = OauthToken.from_dict(body)

    if oauth_token.client_id == user_client_id:
        token = _get_management_token(client_id=oauth_token.client_id, client_secret=oauth_token.client_secret)
        return token

    aud = util.maybe_raise_for_env("XCUBE_HUB_OAUTH_AUD")
    token = _get_management_token()
    res = get_user_by_credentials(token=token,
                                  client_id=oauth_token.client_id,
                                  client_secret=oauth_token.client_secret)

    user = User.from_dict(res[0])
    permissions = users.get_permissions_by_user_id(user.user_id, token=token)
    permissions = users.get_permissions(permissions=permissions)
    claims = {
        "iss": "https://xcube-gen.brockmann-consult.de/",
        "aud": [aud],
        "scope": " ".join(permissions),
        "gty": "client-credentials",
        "email": user.email,
        "sub": users.create_user_id_from_email(user.email),
        "permissions": permissions
    }

    if user.app_metadata and user.app_metadata.geodb_role:
        claims["https://geodb.brockmann-consult.de/dbrole"] = user.app_metadata.geodb_role

    return create_token(claims)
Example #3
0
    def test_supplement_user(self):
        user = User(email='*****@*****.**',
                    user_id='drwho',
                    username='******',
                    family_name='who',
                    given_name='dr',
                    name='drwho',
                    password='******',
                    connection='Init',
                    app_metadata={'geodb_role': 'test_role'},
                    user_metadata=UserUserMetadata())

        subscription = Subscription(
            subscription_id='ab123',
            email="*****@*****.**",
            plan='free',
            guid='dfvdsv',
            client_id='fdvdv',
            client_secret='sdfvsdvdf',
            units=1000,
            unit='punits',
            first_name='Peter',
            last_name='Pettigrew',
            start_date="2000-01-01",
        )

        res = users.supplement_user(user, subscription)

        self.assertEqual(43, len(res.password))
        self.assertEqual('fdvdv', res.user_metadata.client_id)
        self.assertEqual('sdfvsdvdf', res.user_metadata.client_secret)
        self.assertEqual('a10e508275d003230af34c3b3a5f327e6', res.user_id)
Example #4
0
    def test_get_user_by_credentials(self, m):
        user = User(email='*****@*****.**')
        m.get('https://edc.eu.auth0.com/api/v2/users', json=[user.to_dict()])

        res = oauth.get_user_by_credentials(token='dfasvdsav',
                                            client_id='döoasvnoösdvi',
                                            client_secret='sdvdsv')

        self.assertEqual(1, len(res))

        m.get('https://edc.eu.auth0.com/api/v2/users', json=[])

        with self.assertRaises(api.ApiError) as e:
            oauth.get_user_by_credentials(token='dfasvdsav',
                                          client_id='döoasvnoösdvi',
                                          client_secret='sdvdsv')

        self.assertEqual(404, e.exception.status_code)
        self.assertEqual('No users found.', str(e.exception))

        m.get('https://edc.eu.auth0.com/api/v2/users',
              json=[user.to_dict(), user.to_dict()])

        with self.assertRaises(api.ApiError) as e:
            oauth.get_user_by_credentials(token='dfasvdsav',
                                          client_id='döoasvnoösdvi',
                                          client_secret='sdvdsv')

        self.assertEqual(400, e.exception.status_code)
        self.assertEqual('More than one user found.', str(e.exception))

        m.get('https://edc.eu.auth0.com/api/v2/users',
              text='Error',
              status_code=400)

        with self.assertRaises(api.ApiError) as e:
            oauth.get_user_by_credentials(token='dfasvdsav',
                                          client_id='döoasvnoösdvi',
                                          client_secret='sdvdsv')

        self.assertEqual('Error', str(e.exception))
Example #5
0
    def test_get_permissions_by_user_id(self, m):
        user = User(email='*****@*****.**',
                    user_id='drwho',
                    username='******',
                    family_name='who',
                    given_name='dr',
                    name='drwho',
                    password='******',
                    user_metadata={
                        'client_id': 'snört',
                        'client_secret': 'sdvdsv'
                    },
                    connection='Init',
                    app_metadata={'geodb_role': 'test_role'})

        m.get(f"https://edc.eu.auth0.com/api/v2/users/drwho/permissions",
              json=user.to_dict())

        res = users.get_permissions_by_user_id('drwho', token='atoken')

        self.assertDictEqual(user.to_dict(), res)

        m.get(f"https://edc.eu.auth0.com/api/v2/users/drwho/permissions",
              text='No user',
              status_code=404)

        with self.assertRaises(api.ApiError) as e:
            users.get_permissions_by_user_id('drwho', token='atoken')

        self.assertEqual(404, e.exception.status_code)
        self.assertEqual('User not found.', str(e.exception))

        m.get(f"https://edc.eu.auth0.com/api/v2/users/drwho/permissions",
              text='Server Error',
              status_code=500)

        with self.assertRaises(api.ApiError) as e:
            users.get_permissions_by_user_id('drwho', token='atoken')

        self.assertEqual(400, e.exception.status_code)
        self.assertEqual('Server Error', str(e.exception))
Example #6
0
    def _get_user(self, user_id, token: str, raising=True) -> Optional[User]:
        r = requests.get(f"https://{self._domain}/users/auth0|{user_id}",
                         headers=self._get_header(token=token))

        try:
            r.raise_for_status()
        except HTTPError as e:
            if raising:
                raise api.ApiError(r.status_code, str(e))
            else:
                return None

        return User.from_dict(r.json())
Example #7
0
    def test_get_request_body_from_user(self):
        user = User(email='*****@*****.**',
                    user_id='drwho',
                    username='******',
                    family_name='who',
                    given_name='dr',
                    name='drwho',
                    password='******',
                    user_metadata={
                        'client_id': 'snört',
                        'client_secret': 'sdvdsv'
                    },
                    connection='Init',
                    app_metadata={'geodb_role': 'test_role'})
        res = users.get_request_body_from_user(user)

        for k, v in res.items():
            self.assertIsNotNone(v)
Example #8
0
    def get_subscription(self, service_id: str, subscription_id: str,
                         token: str):
        r = requests.get(
            f"https://{self._domain}/users/auth0|{subscription_id}",
            headers=self._get_header(token=token))

        try:
            r.raise_for_status()
        except HTTPError as e:
            raise api.ApiError(r.status_code, str(e))

        user = User.from_dict(r.json())

        if service_id not in user.user_metadata.subscriptions:
            raise api.ApiError(
                404,
                f"Subscription {subscription_id} not found in service {service_id}"
            )

        return user.user_metadata.subscriptions[service_id]
Example #9
0
    def test_get_token(self, m):
        user = User(email='*****@*****.**',
                    user_id='drwho',
                    username='******',
                    family_name='who',
                    given_name='dr',
                    name='drwho',
                    password='******',
                    user_metadata={
                        'client_id': 'snört',
                        'client_secret': 'sdvdsv'
                    },
                    connection='Init',
                    app_metadata={'geodb_role': 'test_role'})
        m.get('https://edc.eu.auth0.com/api/v2/users', json=[user.to_dict()])

        m.post("https://edc.eu.auth0.com/oauth/token",
               json={'access_token': 'asdcaswdc'})

        m.get(f"https://edc.eu.auth0.com/api/v2/users/drwho/permissions",
              json=[
                  {
                      'permission_name': 'manage:collections'
                  },
              ])

        token = {
            'client_id': 'dfsv',
            'client_secret': 'thdrth',
            'aud': 'audience',
            'grant_type': 'password'
        }
        res = oauth.get_token(body=token)

        self.assertIn('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', res)

        token = {
            'client_id': 'id',
            'client_secret': 'sdvdsv',
            'aud': 'audience',
            'grant_type': 'password'
        }
        res = oauth.get_token(body=token)

        self.assertEqual('asdcaswdc', res)

        m.post("https://edc.eu.auth0.com/oauth/token",
               text='error',
               status_code=401)

        with self.assertRaises(Unauthorized) as e:
            res = oauth.get_token(body=token)

        self.assertEqual(
            '401 Unauthorized: 401 Client Error: None for url: https://edc.eu.auth0.com/oauth/token',
            str(e.exception))

        m.post("https://edc.eu.auth0.com/oauth/token",
               json={'access_token_fail': 'asdcaswdc'})

        with self.assertRaises(Unauthorized) as e:
            res = oauth.get_token(body=token)

            self.assertEqual(
                '401 Unauthorized: 401 Client Error: None for url: https://edc.eu.auth0.com/oauth/token',
                str(e.exception))
Example #10
0
    def add_subscription(self,
                         service_id: str,
                         subscription: Subscription,
                         token: str,
                         prefer: str = "resolution=merge-duplicates"):
        user_id = util.create_user_id_from_email(subscription.email)
        user = self._get_user(user_id=user_id, raising=False, token=token)
        new_user = False
        if user is None:
            new_user = True
            user = User()
            user.user_id = util.create_user_id_from_email(subscription.email)
            user.username = util.create_user_id_from_email(subscription.email)
            user.email = subscription.email
            user.first_name = subscription.first_name
            user.last_name = subscription.last_name
            user.user_metadata = UserUserMetadata(subscriptions={})
            user = users.supplement_user(user=user, subscription=subscription)
            user.blocked = False
            user.email_verified = True
            user.connection = "Username-Password-Xcube"

        if user.app_metadata is None:
            user.app_metadata = UserAppMetadata()

        subscription.subscription_id = user.username
        subscription.client_id = subscription.client_id or user.user_metadata.client_id
        subscription.client_secret = subscription.client_secret or user.user_metadata.client_secret
        if subscription.start_date is None:
            subscription.start_date = datetime.datetime.now().strftime(
                "%Y-%m-%d")

        # EOX requires idempotent adding. However, we should think about reintroducing that as returning 409 would
        # if service_id in user.user_metadata.subscriptions:
        #     raise api.ApiError(409, f"The subscription {subscription.subscription_id} exists for service {service_id}.")

        role_id = None
        if service_id == "xcube_geodb":
            role_id_manage = util.maybe_raise_for_env(
                "GEODB_AUTH_ROLE_ID_MANAGE")
            role_id_free = util.maybe_raise_for_env("GEODB_AUTH_ROLE_ID_FREE")
            role_id_user = util.maybe_raise_for_env("GEODB_AUTH_ROLE_ID_USER")

            if subscription.unit != "cells":
                raise api.ApiError(400, "Wrong unit for a geodb subscription")

            if subscription.plan == "manage":
                role_id = role_id_manage
            elif subscription.plan == "freetrial":
                role_id = role_id_free
            else:
                role_id = role_id_user

            user.app_metadata = UserAppMetadata(geodb_role="geodb_" +
                                                subscription.guid)
            geodb.register(subscription=subscription, raise_on_exist=False)
            roles = {"roles": [role_id_manage, role_id_free, role_id_user]}

            requests.delete(
                f"https://{self._domain}/users/auth0|{user_id}/roles",
                json=roles,
                headers=self._get_header(token=token))

        if service_id == "xcube_gen":
            if subscription.unit != "punits":
                raise api.ApiError(400,
                                   "Wrong unit for a xcube gen subscription")

            role_id = util.maybe_raise_for_env("XCUBE_GEN_ROLE_ID")
            try:
                punits.override_punits(
                    user_id=user.email,
                    punits_request=dict(punits=dict(
                        total_count=int(subscription.units))))
            except (DatabaseError, ClientError) as e:
                raise api.ApiError(400, str(e))

        if service_id == "xcube_geoserv":
            role_id = util.maybe_raise_for_env("XCUBE_GEOSERV_ID")

        subscription.role = role_id

        if new_user:
            user.user_metadata.subscriptions[service_id] = subscription
            user_dict = get_request_body_from_user(user)
            r = requests.post(f"https://{self._domain}/users",
                              json=user_dict,
                              headers=self._get_header(token=token))
        else:
            user.user_metadata.subscriptions[service_id] = subscription
            user_dict = dict(user_metadata=user.user_metadata.to_dict(),
                             app_metadata=user.app_metadata.to_dict())
            r = requests.patch(f"https://{self._domain}/users/auth0|{user_id}",
                               json=user_dict,
                               headers=self._get_header(token=token))

        with open('debug.txt', 'a') as f:
            f.write('__________________________________\n\n')
            f.write(json.dumps(self._get_header(token=token)) + '\n\n')
            f.write(self._domain + '\n\n')
            f.write('\n\n')

        try:
            r.raise_for_status()
        except HTTPError as e:
            raise api.ApiError(r.status_code, str(e))

        if new_user:
            role = {"roles": [role_id]}
            r = requests.post(
                f"https://{self._domain}/users/auth0|{user_id}/roles",
                json=role,
                headers=self._get_header(token=token))
        else:
            role = {"roles": [role_id]}
            r = requests.post(
                f"https://{self._domain}/users/auth0|{user_id}/roles",
                json=role,
                headers=self._get_header(token=token))

        try:
            r.raise_for_status()
        except HTTPError as e:
            raise api.ApiError(r.status_code, str(e))

        return subscription
Example #11
0
def get_request_body_from_user(user: User):
    res = user.to_dict()
    for k, v in res.items():
        res[k] = v.isoformat() if isinstance(v, datetime) else v

    return {k: v for k, v in res.items() if v is not None}