def post(self): try: args = parser.parse_args() if (args['device'] is None) or (args['login'] is None) or ( args['password'] is None): return {'success': False, 'errno': ERRNO_FIELDS_ABSENT}, 400 pass_md5 = hashlib.md5( args['password'].encode('utf-8')).hexdigest() user = User.query.filter(User.login == args['login'], User.password == pass_md5).one_or_none() if user is None: log.info("Invalid login/password") return {'success': False, 'errno': ERRNO_INVALID_PASSWORD}, 403 new_token = Token(token=str(uuid.uuid4()), user_id=user.id, device=args['device']) if args['expires'] is not None: new_token.expires_at = datetime.fromtimestamp(args['expires'] / 1000.0) db.session.add(new_token) db.session.commit() log.info("Created new token: %s" % new_token.token) return {'token': new_token.token} except Exception as e: db.session.rollback() log.exception(e) return {'success': False, 'errno': ERRNO_INTERNAL_UNKNOWN}, 500
def login(): ''' User login ''' sent_data = request.get_json(force=True) valid = validate(sent_data, LOGIN_RULES) if valid is not True: response = jsonify(status='error', message="Please provide valid details", errors=valid) response.status_code = 400 return response data = { 'email': sent_data['email'], 'password': sent_data['password'], } # Check if email exists logged_user = User.get_user(data['email']) if logged_user is not None: # Check password if check_password_hash(logged_user.password, data['password']): if logged_user.activation_token is not None: response = jsonify({ 'status': 'error', 'message': "Please confirm your email address" }) response.status_code = 401 return response token_ = get_token(logged_user.id) Token.save({ 'user_id': logged_user.id, 'access_token': token_, }) response = jsonify({ 'status': 'ok', 'message': 'You have been successfully logged in', 'access_token': token_, 'user': { 'username': logged_user.username, 'email': logged_user.email } }) response.status_code = 200 # response.headers['auth_token'] = token return response response = jsonify({ 'status': 'error', 'message': "Invalid email or password" }) response.status_code = 401 return response
def logout(): ''' User logout ''' token = Token.query.filter_by( access_token=request.headers.get('Authorization')).first() Token.delete(token.id) response = jsonify({ 'status': 'ok', 'message': "You have successfully logged out" }) response.status_code = 200 return response
def user_auth(): auth = request.authorization if auth.username is None: return response_with(resp.MISSING_PARAMETERS_422) try: user = db.session.query(User).filter_by(username=auth.username).first() if (check_password_hash(user.password, auth.password)): token = Token(user_uuid=user.uuid) token.create() return response_with(resp.SUCCESS_201, value={"data": token.get_as_dict()}) else: return response_with(resp.UNAUTHORIZED_403) except Exception as e: print(e) return response_with(resp.UNAUTHORIZED_403)
def get_user(token_id, socket_id=None): """ Get user object by token """ if token_id is not None: try: token = Token.get(token_id, fields={'user'}) except ErrorWrong: token = Token(id=token_id) token.save() else: if token.user: return User.get(ids=token.user) elif socket_id is not None: try: socket = Socket.get(socket_id, fields={'user'}) except ErrorWrong: pass else: if socket.user: return User.get(ids=socket.user) return User()
def put(self): try: args = parser.parse_args() if (args['device'] is None) or (args['login'] is None) or ( args['password'] is None): return {'success': False, 'errno': ERRNO_FIELDS_ABSENT}, 400 pass_md5 = hashlib.md5( args['password'].encode('utf-8')).hexdigest() new_user = User(login=args['login'], password=pass_md5) db.session.add(new_user) new_token = Token(token=str(uuid.uuid4()), user=new_user, device=args['device']) if args['expires'] is not None: new_token.expires_at = datetime.fromtimestamp(args['expires'] / 1000.0) db.session.add(new_token) db.session.commit() return {'token': new_token.token} except Exception as e: db.session.rollback() log.error(e) return {'success': False, 'errno': ERRNO_INTERNAL_UNKNOWN}, 500
async def handle(request, data): """ By bot """ # TODO: avatar # TODO: the same token # No access if request.user.status < 2: raise ErrorAccess('social') fields = { 'id', 'login', 'avatar', 'name', 'surname', 'title', 'phone', 'mail', 'social', 'status', # 'subscription', # 'balance', } users = User.get( social={'$elemMatch': { 'id': request.network, 'user': data.user, }}, fields=fields) if len(users) > 1: await report.warning( "More than 1 user", { 'network': request.network, 'social_user': data.user, 'social_login': data.login, }, ) elif len(users): new = False user = users[0] # Action tracking Track( title='acc_auth', data={ 'type': 'bot', 'network': request.network, }, user=user.id, ).save() # Register else: new = True user = await reg(request, data, 'bot') # Assignment of the token to the user if not request.token: raise ErrorAccess('auth') try: token = Token.get(ids=request.token, fields={'user'}) except ErrorWrong: token = Token(id=request.token) if token.user and token.user != user.id: await report.warning( "Reauth", { 'from': token.user, 'to': user.id, 'token': request.token }, ) token.user = user.id token.save() # Response return { **user.json(fields=fields), 'new': new, }
def setUp(self): ''' Set up test data ''' self.main = create_app('testing') self.app = self.main.test_client() self.app_context = self.main.app_context() self.app_context.push() with self.app_context: db.init_app(self.main) db.create_all() self.sample_user = { 'username': '******', 'email': '*****@*****.**', 'password': '******', 'confirm_password': '******' } self.exist_user = { 'username': '******', 'email': '*****@*****.**', 'password': '******', 'confirm_password': '******' } self.unconfirmed_user = { 'username': '******', 'email': '*****@*****.**', 'password': '******', 'confirm_password': '******', 'activation_token': 'AvauDT0T7wo_O6vnb5XJxKzuPteTIpJVv_0HRokS' } self.business_data = { 'name': 'Inzora rooftop coffee', 'description': 'We have best coffee for you,', 'category': 'Coffee-shop', 'country': 'Kenya', 'city': 'Nairobi' } # Business sample data self.rev_business_data = { 'name': 'KFC', 'description': 'Finger lickin\' good', 'category': 'Food', 'country': 'Kenya', 'city': 'Nairobi' } with self.main.test_request_context(): # Orphan id: User id that will be used to create an orphan token orphan_user = User(username="******", email="*****@*****.**", password=self.sample_user['password']) user = User(username=self.sample_user['username'], email=self.sample_user['email'], password=generate_password_hash( self.sample_user['password']), activation_token=None) unconfirmed_account = User( username=self.unconfirmed_user['username'], email=self.unconfirmed_user['email'], password=generate_password_hash( self.unconfirmed_user['password']), activation_token=self.unconfirmed_user['activation_token']) db.session.add(user) db.session.add(orphan_user) db.session.add(unconfirmed_account) db.session.commit() self.sample_user['id'] = user.id self.orphan_id = orphan_user.id self.unconfirmed_user_id = unconfirmed_account.id db.session.remove() token = Token(user_id=self.sample_user['id'], access_token=get_token(self.sample_user['id'])) orphan_token = Token(user_id=self.orphan_id, access_token=get_token(self.orphan_id)) unconfirmed_user_token = Token(user_id=self.unconfirmed_user_id, access_token=get_token( self.unconfirmed_user_id)) expired_token = Token(user_id=self.sample_user['id'], access_token=get_token( self.sample_user['id'], -3600)) # Create bad signature token # Bad signature: #nt secret key from the one used in our API used # to hash tokens other_signature_token = Token(user_id=self.sample_user['id'], access_token=get_token( self.sample_user['id'], 3600, 'other_signature')) business = Business( user_id=self.sample_user['id'], name=self.rev_business_data['name'], description=self.rev_business_data['description'], category=self.rev_business_data['category'], country=self.rev_business_data['country'], city=self.rev_business_data['city'], ) db.session.add(token) db.session.add(orphan_token) db.session.add(expired_token) db.session.add(unconfirmed_user_token) db.session.add(other_signature_token) db.session.add(business) db.session.commit() self.test_token = token.access_token self.expired_test_token = expired_token.access_token self.other_signature_token = other_signature_token.access_token self.orphan_token = orphan_token.access_token self.unconfirmed_user_token = unconfirmed_user_token.access_token
async def auth(request, method, data, by): """ Authorization / registration in different ways """ # TODO: Сокет на авторизацию на всех вкладках токена # TODO: Перезапись информации этого токена уже в онлайне # TODO: Pre-registration data (promos, actions, posts) # TODO: the same token # TODO: Only by token (automaticaly, without any info) # No access if request.user.status < 2: raise ErrorAccess(method) # Data preparation # TODO: optimize fields = { 'id', 'login', 'avatar', 'name', 'surname', 'title', 'phone', 'mail', 'social', 'status', # 'subscription', # 'balance', } # Authorize if by == 'phone': handler = pre_process_phone else: handler = process_lower new = False login_processed = handler(data.login) users = User.get(fields=fields, **{by: login_processed}) if users: if len(users) > 1: await report.warning( "More than 1 user", {by: data.login}, ) user = users[0] else: new = True if new: # Register user = await reg(request, data, by) else: # NOTE: Remove this if no password verification is required # Check password password = process_password(data.password) users = User.get(id=user.id, password=password, fields={}) if not users: raise ErrorWrong('password') # Action tracking Track( title='acc_auth', data={ 'type': by, 'ip': request.ip, }, user=user.id, ).save() # Assignment of the token to the user if not request.token: raise ErrorAccess(method) try: token = Token.get(ids=request.token, fields={'user'}) except ErrorWrong: token = Token(id=request.token) if token.user and token.user != user.id: await report.warning( "Reauth", { 'from': token.user, 'to': user.id, 'token': request.token }, ) token.user = user.id token.save() # TODO: Pre-registration data (promos, actions, posts) # Update online users await online_start(request.sio, request.token) # Response return { **user.json(fields=fields), 'new': new, }