Пример #1
0
    def patch(self) -> (str, int):
        """
		API that allows a user change their password in the users table
		Parameters can be passed using a PATCH request that contains a JSON
		with the following fields:
		:param email: users email address
		:param password_old: users current password
		:param password_new: users new password that they want to replace
							 password_old
		:type email: string
		:type password_old: string
		:type password_new: string
		:return: A message that indicates whether a user's password has been
				updated. If they have not, the message indicates why not.
		:rtype: JSON
		"""
        args = self.parser.parse_args()
        current_user = Users.find_by_email(args['email'])  #t

        if current_user and Users.verify_hash(
                args['password_old'].encode("utf8"),
                current_user.password.encode("utf8")):
            current_user.password = Users.generate_hash(
                args["password_new"].encode("utf8")
            ).decode(
                "utf8"
            )  # decode necessary so that string (and not binary) is stored in the DB
            current_user.commit()
            return {"message": "Password has been updated"}, 200
        else:
            return {"message": "Incorrect credentials. Please Try again"}, 403
def dummy_user():
    """
    A fixture that creates and saves a user to the database that is to be used for testing purposes
    """
    user = Users("User", "*****@*****.**", Users.generate_hash("wfnbqk".encode("utf8")).decode("utf8"), True, True)
    user.save()
    user.commit()
    return user
Пример #3
0
 def get_dummy_user(self) -> Users:
     """
     Creates a dummy user to be used in the unit tests for Users
     :return: a user
     """
     new_user = Users("fullname", '*****@*****.**',
                      Users.generate_hash('top_secret'.encode("utf-8")),
                      True, True)
     new_user.save()
     new_user.commit()
     return new_user
Пример #4
0
    def setUp(self):
        """ Create testing client version of flask app """
        self.test_app = create_app(DATABASE_NAME='test_analytics',
                                   TESTING=True)
        self.testing_client = self.test_app.test_client()
        self.testing_client_context = self.test_app.app_context()
        self.testing_client_context.push()

        self.dummy_user = Users(
            "Joey", "*****@*****.**",
            Users.generate_hash("1234".encode("utf8")).decode("utf8"), True,
            True)
        self.dummy_user.save()
        self.dummy_user.commit()
Пример #5
0
    def post(self) -> (str, int):
        """
        POST request that allows user to change their credentials in the
        Users table. A valid access JWT is required where the admin
        claim has to be True
        Parameters can be passed using a POST request that contains a JSON with the following fields:
        :required:
            :param email: users current email address
            :type email: str
        :optional:
            :param fullname: users to be fullname
            :param password: users to be password
            :param admin: users to be admin status
            :param activated: users to be activated status
            :type fullname: str
            :type password: str
            :type admin: bool
            :type activated: bool

        :return: A message indicating success or failure and the corresponding response code
        """
        if not get_jwt_claims()['admin']:
            abort(HTTPStatus.FORBIDDEN.value,
                  error="administration privileges required")

        args = self.post_reqparser.parse_args()
        current_user = Users.find_by_email(args["email"])

        if current_user:
            if "fullname" in args:
                current_user.fullname = args["fullname"]
            if "activated" in args:
                current_user.activated = bool(args["activated"])
            if "admin" in args:
                current_user.admin = bool(args["admin"])
            if "password" in args:
                current_user.password = Users.generate_hash(
                    args["password"].encode("utf8")).decode("utf8")

            try:
                current_user.commit()
            except Exception as e:
                logging.error(e)
                return {"message": "failed saving details to database"}, 500

            return {"message": "success"}, 200

        else:
            return {"message": "error: could not find user"}, 403
def dummy_user():
    """ Create and save regular user to the database for duration of test and delete it afterwards """
    user = Users("Dummy", "*****@*****.**",
                 Users.generate_hash("1234".encode("utf8")).decode("utf8"),
                 True, True)

    try:
        user.save()
        user.commit()
    except Exception as e:
        pass

    yield user

    db.session.delete(user)
    db.session.commit()
def admin_user():
    """ Create and save admin user to the database for duration of test and delete it afterwards """
    user = Users("Admin", "*****@*****.**",
                 Users.generate_hash("wfnbqk".encode("utf8")).decode("utf8"),
                 True, True)

    try:
        user.save()
        user.commit()
    except Exception as e:
        pass

    yield user

    db.session.delete(user)
    db.session.commit()
Пример #8
0
    def post(self) -> (dict, int):
        """
        API resource class which creates a new user and adds it to the database
        Parameters can be passed using a POST request that contains a JSON with the following fields:
        :required: valid access JWT where the admin claim has to be true
        :param email: users email address
        :param fullname: users fullname
        :param admin: whether the user will be an admin user or not
        :param password: users password
        :type email: str
        :type fullname: str
        :type admin: str
        :type password: str
        :return: A message indicating a successful or unsuccessful addition of user to the database
        """
        args = self.post_reqparser.parse_args()
        # User needs admin rights to continue
        if not get_jwt_claims()['admin']:
            abort(HTTPStatus.FORBIDDEN.value,
                  error="administration privileges required")

        # Check email address supplied is actually an email address
        args["email"].lower()
        # if not Users.email_regex_checker(args["email"]):
        #     abort(HTTPStatus.BAD_REQUEST.value, error="{} is not a valid email".format(args["email"]))

        # Is the user email already registered
        if self._does_user_exsist(args["email"]):
            abort(HTTPStatus.BAD_REQUEST.value,
                  error='User email exists. email address must be unique')

        # Create new user database entry in users table
        try:
            hashed_password = Users.generate_hash(
                args["password"].encode("utf-8")).decode("utf-8")
            new_user = Users(args["fullname"], args["email"], hashed_password,
                             bool(args["admin"]), False)
            new_user.save()
            new_user.commit()
        except Exception as e:
            abort(HTTPStatus.BAD_REQUEST.value,
                  error=e,
                  admin=get_jwt_claims()['admin'])
        return ({
            "user": "******".format(args["email"])
        }), 201
Пример #9
0
    def generate_access_token(self) -> {str, str}:
        """
        Generate admin access JWT.
        :return: a HTTP authorization header containing a admin access token
        """

        admin_user = Users("Admin user", "*****@*****.**",
                           Users.generate_hash(b"1234").decode("utf8"),
                           True, True)
        admin_user.save()
        admin_user.commit()
        response_login = self.testing_client.post('/login', data=dict(
            email="*****@*****.**", password="******", remember=True))
        response_login_json = response_login.get_json()
        admin_user.delete()
        admin_user.commit()
        return {'Authorization': 'Bearer {}'.format(
            response_login_json["access_token"])}
    def post(self) -> (dict, int):
        """
        API resource class which changes a users password and saves changes to the database
        Parameters can be passed using a POST request that contains a JSON with the following fields:
        :required: valid access JWT where the admin claim may be either true or false
        :param email: users email address
        :param password: the new password which the user wants to store in the database
        :param verify_password: a repitition of the the 'password' param
        :type email: str
        :type password: str
        :type verify_password: str
        :return: A message indicating a successful or unsuccessful change
         """
        args = self.post_reqparser.parse_args()
        user = None

        # User must be an admin
        if not get_jwt_claims()['admin']:
            abort(HTTPStatus.FORBIDDEN.value,
                  error="administration privileges required")

        # get user instance using email address
        if args["email"]:
            user = Users.find_by_email(args["email"])
            if not user:
                abort(HTTPStatus.BAD_REQUEST.value, error="User not found")

        if args["password"] == args["verify_password"]:
            user.password = Users.generate_hash(
                args["password"].encode("utf-8")).decode("utf-8")

        try:
            user.save()
            user.commit()
        except exc.SQLAlchemyError as e:
            logging.critical(e)
            abort(HTTPStatus.BAD_REQUEST.value,
                  error="User password not changed")

        return {"user": "******".format(args["email"])}, 201
def test_user_email_duplication() -> NoReturn:
    """
    test that duplication of a user email is not possible
    """
    json_data = {
        "email": "*****@*****.**",
        "fullname": "fullname",
        "admin": True,
        "password": "******"
    }
    new_user = Users("fullname", '*****@*****.**',
                     Users.generate_hash('top_secret'.encode("utf-8")), True,
                     True)
    new_user.save()
    new_user.commit()
    response = dependencies.client.post('/admin/create_new_user',
                                        json=json_data,
                                        headers=dependencies.auth_header,
                                        follow_redirects=True)
    assert response.status_code == 400
    new_user.delete()
    new_user.commit()
    def post(self) -> (str, int):
        """
		POST requests, activate user's account and change their password
		Parameters can be passed using a POST request that contains a JSON of the following fields:
		:param fullname: users fullname
		:param email: users email address
		:param password: users password that was sent when they were added on the admin page
		:type fullname: string
		:type email: string
		:type password: string
		:return: A message that indicates whether a user has been registered. If they have not, the message indicates why not
		"""
        args = self.parser.parse_args()
        current_user = Users.find_by_email(args['email'])  #t

        if not current_user:
            return {
                'message':
                'User {} is not authorised to access Sharing Cities Dashboard'.
                format(args['email'])
            }, 403

        if not Users.verify_hash(args['password'].encode("utf8"),
                                 current_user.password.encode("utf8")):
            return {
                'message':
                'The password entered does not correspond to the password sent to {}. Please try again'
                .format(args['email'])
            }, 403

        current_user.activated = True
        current_user.password = Users.generate_hash(
            args["password_new"].encode("utf8")).decode("utf8")
        current_user.commit()
        return {
            'message':
            '{}\'s account has been registered. Redirect to login'.format(
                args['email'])
        }, 201
Пример #13
0
    def generate_access_token(self) -> dict:
        """
        Remove the entries that were persisted in the simulate_importer method
        :return: a HTTP authorization header containing a admin access token
        """

        admin_user = Users("Admin user", "*****@*****.**",
                           Users.generate_hash(b"1234").decode("utf8"), True,
                           True)
        admin_user.save()
        admin_user.commit()
        response_login = self.testing_client.post('/login',
                                                  data=dict(
                                                      email="*****@*****.**",
                                                      password="******",
                                                      remember=True))
        response_login_json = response_login.get_json()
        admin_user.delete()
        admin_user.commit()
        return {
            'Authorization':
            'Bearer {}'.format(response_login_json["access_token"])
        }
Пример #14
0
    def post(self):
        args = self.post_reqparser.parse_args()
        user = None

        #User must be an admin
        if not get_jwt_claims()['admin']:
            abort(HTTPStatus.FORBIDDEN.value, error="administration privileges required")

        #get user instance using email
        if args["email"]:
            user = Users.find_by_email(args["email"])
            if not user:
                abort(HTTPStatus.BAD_REQUEST.value, error="User not found")

        if args["password"] == args["verify_password"]:
            user.password = Users.generate_hash(args["password"].encode("utf-8"))

        try:
            user.save()
            user.commit()
        except exc.SQLAlchemyError:
            abort(HTTPStatus.BAD_REQUEST.value, error="User password not changed")

        return {"user": "******".format(args["email"])}, 201
    def post(self) -> (str, int):
        """
        POST request endpoint. Set user password to a system generated
        password and send password to user's email
        """

        args = self.parser.parse_args()
        current_user = Users.find_by_email(args["email"])

        if current_user:
            system_password = self.generate_random_password(
                self.system_password_length)

            if self.send_forgot_password_email(current_user.fullname,
                                               current_user.email,
                                               system_password):
                current_user.password = Users.generate_hash(
                    system_password.encode("utf8")).decode("utf8")
                current_user.commit()
                return {"message": "success"}, 200
            else:
                return {"message": "could not send email"}, 500
        else:
            return {"message": "cannot find user"}, 403