def create_new_user(username, email, password): """ Add a new user :param username: :param email: :param password: :return: Json Object {username, token}| {error} """ password = password.strip() if not re.match("^[a-zA-Z0-9_]*$", username): raise InvalidUsage( 'the only special char available for username is _') if len(password) < 8: raise InvalidUsage('password must be greater than 7 chars') if not User.validate_new_email(email): raise InvalidUsage('email already exists or not valid') if User.get_by_id(username) is not None: raise InvalidUsage('username already exists') key = ndb.Key(User, username) new_user = User(key=key, username=username, email=email, password=pbkdf2.crypt( password, iterations=config.CRYPT_LOG_ROUNDS)) new_user.put() token = new_user.encode_auth_token() return {'username': username, 'token': token}
def login(): ''' User Login parameters: user, password response: 200: jwt: token roles: list of roles user is authorized for 400: missing credentials 401: not authorized ''' if not request.is_json: raise InvalidUsage("Missing JSON in request") params = request.get_json() user = params.get('user', None) password = params.get('password', None) if not user: raise InvalidUsage("Missing username parameter") if not password: raise InvalidUsage("Missing password paramter") db_user = User.query.filter_by(username=user).first() if not db_user or db_user.password != password: raise UnauthorizedUse() roles = [role.name for role in db_user.roles] return jsonify(jwt=create_jwt(identity=user), roles=roles), 200
def set_count(): ''' Manually sets the count on a given day or delete count if personcount is empty Used for Admins to alter mistakes from callers ''' params = request.get_json() personcount = params.get('numberOfPeople') shelterID = params.get('shelterID') day = params.get('day') if not all((shelterID, day)): raise InvalidUsage("Missing data", status_code=400) try: parsed_day = pendulum.parse(day, strict=False) except ValueError: raise InvalidUsage("Can't parse date", status_code=400) if not personcount: count = Count().query.filter_by(shelter_id=shelterID, day=parsed_day.isoformat()).delete() log = Log(shelter_id=shelterID, from_number='web', contact_type="Admin", input_text="-", action="delete_count", parsed_text="") ret = {"personcount": None, "bedcount": None, "shelterID": shelterID} else: shelter = Shelter.query.get(int(shelterID)) count = Count(shelter_id=shelterID, personcount=personcount, bedcount=shelter.capacity - int(personcount), day=parsed_day.isoformat(), time=func.now()) log = Log(shelter_id=shelterID, from_number="web", contact_type="Admin", input_text=personcount, action="save_count", parsed_text=personcount) ret = { "personcount": count.personcount, "bedcount": count.bedcount, "shelterID": shelterID } db.session.merge(count) try: db.session.add(log) db.session.commit() except IntegrityError as e: # calls has a foreign key constraint linking it to shelters logging.error(e.orig.args) db.session().rollback() raise ServerError('Error Saving Data') return jsonify({"success": True, "counts": ret})
def load_user_by_username(username): """ Login user :param username: :return: User """ if not username: raise InvalidUsage('missing required parameters') user = ndb.Key(User, username).get() if not user: raise InvalidUsage('user does not exist!') return user
def update_shelter(): ''' Updates or creates an new shelter Response: 200: JSON object with the shelter data ''' form = newShelterForm() shelter = {} shelter['id'] = form.id.data shelter['name'] = form.name.data shelter['description'] = form.description.data shelter['phone'] = form.phone.data or None shelter['login_id'] = form.login_id.data shelter['capacity'] = form.capacity.data shelter['active'] = form.active.data shelter['visible'] = form.visible.data shelter['public'] = form.public.data shelter = Shelter(**shelter) try: shelter = db.session.merge(shelter) db.session.commit() except IntegrityError as e: logging.warning(e.orig.args) db.session().rollback() raise InvalidUsage("Values must be unique", status_code=400) return jsonify(shelter.toDict())
def decode_auth_token(auth_token): """ Validates the auth token :param auth_token: :return: Json Object {username} | {error} """ try: payload = jwt.decode(auth_token, config.SECRET_KEY) blacklisted = Blacklist.query(Blacklist.token == auth_token).get() if blacklisted: raise InvalidUsage('This token is not valid anymore') return {'username': payload['sub']} except jwt.ExpiredSignatureError: raise InvalidUsage('Signature expired. Please log in again') except jwt.InvalidTokenError: raise InvalidUsage('Invalid token. Please log in again')
def newfn(): errors = {} for a in _args: if a not in request.args: errors[a] = 'This field is required' if errors: raise InvalidUsage(payload={'errors': errors}) return func()
def load_timeline(entity_key): """ load a timeline by its key :param entity_key: :return: timeline entity | {error} """ try: timeline = ndb.Key(urlsafe=entity_key).get() except TypeError: return { 'error': 'problem with this timeline. sure this link is valid?' } if not timeline: raise InvalidUsage('timeline does not exist') if not timeline.active: raise InvalidUsage('timeline does not exist anymore') return timeline
def load_user_by_token(token): """ load an user from its token :param token: :return: User object | {error} """ token = User.decode_auth_token(token) user = User.get_by_id(token['username']) if user is not None: return user raise InvalidUsage('this user does not exist anymore')
def login_user(username, password): """ Login user :param username: :param password: :return: Json Object {username, token} """ if not username or not password: raise InvalidUsage('missing required parameters') user = ndb.Key(User, username).get() if not user: raise InvalidUsage('user does not exist, sign in now!') if user.password != pbkdf2.crypt( password, user.password, iterations=config.CRYPT_LOG_ROUNDS): raise InvalidUsage('wrong password') token = user.encode_auth_token() return {'username': user.username, 'token': token}
def submission(): if request.method == 'POST': body = request.json submission_title = body.get('submission_title', None) try: # Get the submission files and a datapackage created with those files + other metadata submission_files, dp = get_submission_files(submission_title) # Add the datapackage to the minio s3 store add_datapackage(dp) for submission_file in submission_files: validate_submission_file_task.delay(submission_file) res = { 'accepted': True } return json.dumps(res) except Exception as e: raise e raise InvalidUsage( f'Error when starting to validate a submission: {str(e)}' ) return None
def change_password(self, password): if len(password.strip()) < 8: raise InvalidUsage('password must be greater than 7 chars') self.password = pbkdf2.crypt(password, iterations=config.CRYPT_LOG_ROUNDS) self.put()