def register_user(email, password, password_confirmation, token=None, selector=None): if password != password_confirmation: raise Exception('Passwords don\'t match') selector = selector or S() if token: claims = jwt_decode(token) try: user = Q(User).filter(id=claims['user_id']).select('id', 'email').get() if user['email']: raise Exception('Cannot register existing user') except (KeyError, AttributeError): raise Exception('Invalid token for user registration') user = upgrade_user( user['id'], email, password, selector=(selector.get('user') or S()).merge(S(entity=S('id'))) ) else: user = create_user( email, password=password, selector=(selector.get('user') or S()).merge(S(entity=S('id'))) ) token = jwt({ 'user_id': user['id'], 'entity_id': user['entity']['id'], 'role': 'default' }) return { 'token': token, 'user': user }
def run(self, purpose, user_email=None, organisation=None): if not user_email and not organisation: # TODO: Better error. raise Exception('Must supply one of "user" or "organisation"') api_token_id = ( Q(APIToken) .insert(purpose=purpose) .select('id') .get() )['id'] claims = { 'api_token_id': api_token_id, 'role': 'user' } if user_email: results = ( Q(User) .filter(email=user_email) .select('id', entity=S('id')) .get() ) claims['user_id'] = results['id'] elif organisation: results = ( Q(Organisation) .filter(name=organisation) .select('id', entity=S('id')) .get() ) if results['entity']['id']: claims['entity_id'] = results['entity']['id'] token = jwt(claims) print(f'Claims: {repr(claims)}') print(f'API token: {token}')
def resolve(self, ctx): input = ctx.parse_input() try: token = input['token'] claims = jwt_decode(token) query = Q(User).filter(id=claims['user_id']) # TODO: This is a little inefficient, but is needed to # confirm the user actually exists. if query.select('id').get() is None: raise Exception except Exception: # TODO: Check more. # TODO: These should be composable, but the nested select # from Polecat doesn't seem to be working as expected. entity_id = Q(Entity).insert().select('id').get()['id'] query = (Q(User).insert(entity=entity_id, anonymous=True)) token = None if ctx.selector and 'user' in ctx.selector.lookups: query = query.select( S(entity=S('id')).merge(ctx.selector.lookups.get('user'))) user = query.get() if not token: token = jwt({ 'user_id': user['id'], 'entity_id': (user['entity'] or {}).get('id'), 'role': 'default' }) return {'token': token, 'user': user}
def resolve(self, email, password): result = ( Q(User) .filter(email=email, password=password) .select('id') .get() ) return jwt({'userId': result['id']})
def test_upgrade_from_non_anonymous(self, db, factory): anon_user = factory.User(email='*****@*****.**', password=None) token = jwt({ 'user_id': anon_user.id, 'entity_id': anon_user.entity.id, 'role': 'default' }) with pytest.raises(Exception, match=r'Cannot register existing user'): register_user('*****@*****.**', 'a', 'a', token=token)
def test_upgrade_from_anonymous(self, db, factory): anon_user = factory.User(email=None, password=None) token = jwt({ 'user_id': anon_user.id, 'entity_id': anon_user.entity.id, 'role': 'default' }) result = register_user('*****@*****.**', 'a', 'a', token=token, selector=S(user=S('email'))) assert result['user'] is not None assert result['user']['id'] == anon_user.id assert result['user']['email'] == '*****@*****.**'
def resolve(self, ctx): input = ctx.parse_input() email = input['email'] password = input['password'] result = (Q(User).filter(email=email, password=password)) selector = S('id', entity=S('id')) selector.merge(ctx.selector.get('user')) result = result.select(selector).get() if not result: raise AuthError('Invalid email/password') return { 'token': jwt({ 'user_id': result['id'], 'entity_id': result['entity']['id'], 'role': 'user' }), 'user': result }
def resolve(self, ctx): input = ctx.parse_input() result = (Q(User).filter( email=input['email'], password=input['password']).select('id').get()) return {'token': jwt({'userId': result['id']})}