def load_user_from_header_authorization(): if 'Authorization' not in request.headers: return jsonify({ 'status': 401, 'message': 'No HTTP Authorization HEADER found.' }), 401 else: auth_header = request.headers.get('Authorization') # check the different supported Authorization methods if 'basic' in auth_header.lower(): enc = base64.b64decode(auth_header[6:]).decode() email, password = enc.split(':') # get the user user = User.get_by_email(email=email) elif 'bearer' in auth_header.lower(): token = auth_header[7:] # get the user try: user = User.get_from_access_token(token=token) except BadSignature: return jsonify({ 'status': 401, 'message': 'The passed access token was not valid.' }), 401 except SignatureExpired: return jsonify({ 'status': 401, 'message': 'Your access token has expired. Please request a ' 'new one.' }), 401 # password is not required password = None else: return jsonify({ 'status': 501, 'message': 'Only Basic and Bearer Authorization are implemented' }), 501 return check_user_logged_in(user, password, check_activation=True)
def get(self, user_id): """GET User Returns all information associated to the user of user_id. This route requires an active login and is limited to the user himself and all user of role permission defined in user_route decorator. Defaults to users of role 'superuser' or 'admin' Parameters ---------- user_id : str id of the requested user Returns ------- user : JSON JSON serialized content of the User information. """ # get User user = User.get(_id=user_id) # check user exists if user is None: return {'status': 404, 'message': 'User not found'}, 405 return user.to_dict(stringify=True), 200
def put(self, user_id): """Request new activation link A PUT request to request a new activation link. This route will overwrite old activation tokens and needs a email client configured. Parameters ---------- user_id : str id of the requested user Returns ------- response : JSON JSON serialized acknowledgement message """ # load the user user = User.get(_id=user_id) if user is None: return {'status': 404, 'message': 'User not found.'}, 404 # create a new activation token token = user.get_activation_token() # build the activation link url = url_for('auth.activation', token=token, user_id=str(user.id), _external=True) # build the activation mail and sent # msg = Message( # 'Your account activation', # recipients=[user.email], # html=ACTIVATION_MAIL_TEMPLATE.format(user.email, url) # ) mail = Mail() mail.send(user.email, 'Your new activation link', ACTIVATION_MAIL_TEMPLATE.format(user.email, url)) return { 'status': 200, 'message': 'A new activation mail has been sent to: %s.' + 'Your user ID is: %s' % (user.email, str(user.id)) }, 200
def get(self): """GET all users Get all users registered in the database. This can only be performed by a superuser or users of a role defined in the decorator function. Returns ------- users : JSON JSON serialized list of all Users """ # get the users users = User.get_all() return {'status': 200, 'found': len(users), 'users': users}, 200
def delete(self, user_id): """Delete the user Delete the requested user. This action can only be performed by the user of user_id himself or any user of role superuser and users of decorated roles (usually 'admin'). The user information will be stored into the backup folder into the json backup file specified in the application cofig Parameters ---------- user_id : str id of the requested user Returns ------- response : JSON acknowledgement message """ # get the user user = User.get(_id=user_id) if user is None: return {'status': 404, 'message': 'User not found.'}, 404 # get the user info d = user.to_dict(stringify=True) # delete user.delete() # store with open(current_app.config.get('DELETED_USER_PATH'), 'w+') as backup: data = json.load(backup) data['users'].append(d) backup.write(data) # return return { 'status': 200, 'acknowledged': True, 'message': 'User has been deleted.' }, 200
def get(self, user_id): """Link Activation This route is used to activate a user account by a GET request. Then the activation token has to be passed by url PARAM like: SERVER/user/user_id/activate?token=YOURTOKEN Parameters ---------- user_id : str id of the requested user Returns ------- user : JSON JSON serialized content of the activated User information. """ # make sure a token was passed token = request.args.get('token') if token is None: return { 'status': 409, 'message': 'No activation token was passed.' }, 409 # load the user user = User.get(_id=user_id) if user is None: return {'status': 404, 'message': 'User not found.'}, 404 # activate if user.activate(token=token): return { 'status': 200, 'acknowledged': True, 'user': user.to_dict(stringify=True) }, 200 else: return { 'status': 400, 'message': 'The activation token is invalid.' }, 400
def post(self, user_id): """Edit user Request an edit to the user of user_id. Any JSON encoded content passed to this route will update the user of user_id. Parameters ---------- user_id : str id of the requested user Returns ------- user : JSON JSON serialized content of the updated User information. """ # get User user = User.get(_id=user_id) # check user exists if user is None: return {'status': 404, 'message': 'User not found'}, 405 # get the data data = request.get_json() if len(data.keys()) == 0: return {'status': 412, 'message': 'No content recieved'}, 412 # update the user try: user.update(data=data) except Exception as e: return {'status': 500, 'message': str(e)}, 500 # return updated user return user.to_dict(stringify=True), 200
def login(): # get the login information if request.authorization is not None: email = request.authorization.get('username') pw = request.authorization.get('password') else: email = request.form.get('email') pw = request.form.get('password') # get the user from mail user = User.get_by_email(email) # no user found if user is None: return jsonify({'status': 404, 'message': 'User not found.'}), 404 # check activation status if not user.is_activated(): return jsonify({ 'status': 409, 'message': 'The user account is not activated yet.' }), 409 # verify password if user.verify_password(pw): return jsonify({ 'user': user.to_dict(stringify=True), 'access_token': user.get_access_token().decode('ascii') }) else: return jsonify({ 'status': 405, 'message': 'password not correct.' }), 405 # @auth_blueprint.route('/activate', methods=['POST']) # def activate(): # # search GET for token # if request.args.get('token') is not None: # token = request.args.get('token') # elif request.form.get('token') is not None: # token = request.form.get('token') # elif request.json.get('token') is not None: # token = request.json.get('token') # else: # return jsonify({'status': 400, 'message': 'No token was passed.'}), 400 # # # split the token # user_id, _ = token.split('::') # user = User.get(user_id) # print(user.to_dict()) # # if user is None: # return jsonify({'status': 404, 'message': 'User not found.'}), 404 # # # activate # if user.activate(token): # return jsonify({'status': 200, 'acknowledged': True}), 200 # else: # return jsonify({'stauts': 409, 'message': 'Token not valid'}), 409
def get(self, email): """Request new activation link or password Request a new account activation mail or a password reset. In this route, the user will be identified by email. Parameters ---------- email : str email of the requested user Returns ------- response : JSON JSON serialized acknowledgement message """ # load the user user = User.get_by_email(email=email) if user is None: return { 'status': 404, 'message': 'This email is not registered.' }, 404 # see what is requested if 'password' in request.args.keys(): mode = 'password' elif 'activation' in request.args.keys(): mode = 'activation' else: # if no mode is given, infer it mode = 'activation' if not user.is_activated() else 'password' # switch mode if mode == 'password': return {'status': 505, 'message': 'Not Implemented'}, 505 elif mode == 'activation': if user.is_activated(): return { 'status': 409, 'message': 'This account is already activated.' }, 409 # generate new token token = user.get_activation_token() # build the activation link url = url_for('auth.activation', token=token, user_id=str(user.id), _external=True) subject = 'Your new activation link' message = ACTIVATION_MAIL_TEMPLATE.format(user.email, url) mail = Mail() mail.send(user.email, subject, message) return { 'status': 200, 'message': 'A new activation mail has been sent to: %s. Your ' 'user ID is: %s' % (user.email, str(user.id)) }, 200
def put(self): """User registration PUT a new user to the database. This user will be registered but not activated. Thus, he will not be able to authorize for any protected routes. Users can be activated by clicking the link sent to the registered email address. Returns ------- user : JSON JSON serialized content of the new User information. """ # get the data data = request.get_json() email = data.get('email') pw = data.get('password') # at least email and password is needed if email is None or pw is None: return { 'status': 400, 'message': 'At least a email and password is needed.' }, 400 # Check if this email already exists if User.email_exists(email=email): return { 'status': 409, 'message': 'The email %s is already registered.' % email }, 409 # create the user user = User(email=email, password=pw, role='user', job_credit=10) user.create() # get an activation token token = user.get_activation_token() # build the activation link url = url_for('auth.activation', token=token, user_id=str(user.id), _external=True) # build the activation mail and sent # msg = Message( # 'Your account activation', # recipients=[user.email], # html=ACTIVATION_MAIL_TEMPLATE.format(email, url) # ) # send the activation mail mail = Mail() mail.send(_to=user.email, subject='Your account activation', message=ACTIVATION_MAIL_TEMPLATE.format(email, url)) return { 'status': 201, 'message': 'An activation mail has been sent to: %s. Your user ' 'ID is: %s.' % (email, str(user.id)) }, 201