Example #1
0
 def on_get(self, req, res, user_id=None):
     if req.get_header('SUPER-ADMIN-KEY') == SUPER_ADMIN_KEY:
         if user_id:
             users = db.fetch_users(user_id=user_id, hide_pass=True)
             if users:
                 data = {
                     'id': user_id,
                     'username': users[0]['username']
                 }
             else:
                 error = {
                     'description': 'Invalid user_id',
                     'details': f"{user_id} doesn't exist."
                 }
                 LOG.error(error)
                 raise generic_error_handler(404, req=req, error_override=error)
         else:
             username = req.params.get('username')
             user_id = req.params.get('id')
             users = db.fetch_users(username=username, user_id=user_id, hide_pass=True)
             data = {'count': len(users),'items': users}
         self.on_success(res, data)
     else:
         error = {
             'description': 'Unauthorized',
             'details': "Permission Denied" 
         }
         LOG.error(error)
         raise generic_error_handler(401, req=req, error_override=error)
Example #2
0
    def on_post(self, req, res):

        skills = req.get_json('skills')

        if not isinstance(skills, list):
            error = {
                'description': 'invalid skills',
                'details': f"'skills' field needs to be an array/list"
            }
            LOG.error(error)
            raise generic_error_handler(400, req=req, error_override=error)

        astronaut = {
            'id': str(uuid.uuid4()),
            'active': True,
            'firstName': req.get_json('firstName', dtype=str, min=3, max=20),
            'lastName': req.get_json('lastName', dtype=str, min=3, max=20),
            'skills': skills,
            'hoursInSpace': req.get_json('hoursInSpace', dtype=int, min=0),
            'picture': req.get_json('picture', dtype=str, min=3)
        }

        try:
            db.add_astronauts_bulk([astronaut])
        except Exception as ex:
            error = {'description': ex}
            LOG.error(error)
            raise generic_error_handler(400, req=req, error_override=error)

        self.on_created(res, astronaut)
Example #3
0
    def on_delete(self, req, res, user_id=None):
        if user_id:
            users = db.fetch_users(None, user_id=user_id, hide_pass=True)

            if users:
                if req.get_header('SUPER_ADMIN_KEY') == SUPER_ADMIN_KEY:
                    db.delete_from_table('users', user_id)
                    if req.params.get('details') == 'true':
                        data = users[0]
                        data['meta'] = {'action': f'user \'{users[0]["username"]}\' has been deleted'}
                        self.on_success(res, data)
                    else:
                        self.on_no_content(res, {})
                else:
                    error = {
                        'description': 'Unauthorized',
                        'details': "Permission Denied" 
                    }
                    LOG.error(error)
                    raise generic_error_handler(401, req=req, error_override=error)
            else:
                error = {
                    'description': 'Invalid user_id',
                    'details': f"{user_id} doesn't exist."
                }
                LOG.error(error)
                raise generic_error_handler(404, req=req, error_override=error)

        else:
            raise generic_error_handler(500, req=req)
Example #4
0
    def on_post(self, req, res):
        if "multipart/form-data" in req.content_type:
            username = req.params.get('username') 
            password = req.params.get('password')
        elif "application/json" in req.content_type:
            username = req.get_json('username', dtype=str, min=3, max=20)
            password = req.get_json('password', dtype=str, min=8, max=20)
        else:
            error = {
                'description': 'Invalid content-type',
                'details': 'Only \'multipart/form-data\' and \'json/application\' allowed'
            }
            LOG.error(error)
            raise generic_error_handler(415, req=req, error_override=error)

        users = db.fetch_users(username)
        if len(users) >= 1:
            error = {
                'description': 'Invalid username',
                'details': f"user '{username}' already exists."
            }
            LOG.error(error)
            raise generic_error_handler(400, req=req, error_override=error)
        else:
            user_id = str(uuid.uuid4())
            pasword = make_password_hashing(password)

            db.create_user(user_id, username, pasword)

            data = {
                'id': user_id,
                'username': username
            }

            self.on_created(res, data)
Example #5
0
    def on_put(self, req, res):
        username = req.get_json('username', dtype=str, min=3, max=20)
        password = req.get_json('password', dtype=str, min=8, max=20)
        new_password = req.get_json('new_password', dtype=str, min=8, max=20)

        users = db.fetch_users(username)

        user_id = str(uuid.uuid4())
        pasword = make_password_hashing(new_password)

        if len(users) == 1:
            if not checking_password_hash(password, users[0]['password']):
                error = {
                    'description': 'Incorrect password entered',
                }
                LOG.error(error)
                raise generic_error_handler(401, req=req, error_override=error)
            else:
                db.replace_user_info(user_id, username, pasword)
                
        elif len(users) > 1:
            error = {
                'description': f"There was more than 1 user found for username: '******'"
            }
            LOG.error(error)
            raise generic_error_handler(400, req=req, error_override=error)
        else:
            db.create_user(user_id, username, pasword)
        
        data = {
            'id': user_id,
            'username': username
        }

        self.on_success(res, data)
Example #6
0
def create_user(id_, username, password):
    conn = create_connection(DATABASE)
    c = conn.cursor()
    try:
        c.execute("INSERT INTO users(id_, username, password) VALUES(?, ?, ?)",
                  (id_, username, password))
        conn.commit()
    except sqlite3.IntegrityError as ex:
        LOG.error(ex)
        raise Exception(ex)
    conn.close()
Example #7
0
def create_table(conn, create_table_sql):
    """ create a table from the create_table_sql statement
    :param conn: Connection object
    :param create_table_sql: a CREATE TABLE statement
    :return:
    """
    try:
        c = conn.cursor()
        c.execute(create_table_sql)
    except Error as ex:
        LOG.error(ex)
        raise Exception(ex)
Example #8
0
def replace_user_info(id_, username, password):
    conn = create_connection(DATABASE)
    c = conn.cursor()
    try:
        c.execute(f"DELETE FROM users WHERE username=?", (username, ))
        c.execute("INSERT INTO users(id_, username, password) VALUES(?, ?, ?)",
                  (id_, username, password))
        conn.commit()
    except sqlite3.IntegrityError as ex:
        LOG.error(ex)
        raise Exception(ex)
    conn.close()
Example #9
0
def create_connection(db_file):
    """ create a database connection to the SQLite database
        specified by db_file
    :param db_file: database file
    :return: Connection object or None
    """
    try:
        conn = sqlite3.connect(db_file)
        return conn
    except Error as ex:
        LOG.error(ex)
        raise Exception(ex)
    return None
Example #10
0
 def on_get(self, req, res, id_):
     params = {'id_': id_}
     astronauts = db.fetch_astronauts(filters=params)
     if astronauts:
         data = astronauts[0]
     else:
         error = {
             'description': 'Invalid astronaut',
             'details': f"An astronaut with id '{id_}' doesn't exist."
         }
         LOG.error(error)
         raise generic_error_handler(404, req=req, error_override=error)
     self.on_success(res, data)
Example #11
0
def init_session():
    conn = create_connection(DATABASE)
    if conn is not None:
        drop_table('users')
        drop_table('astronauts')
        create_table(conn, sql_create_users_table)
        create_table(conn, sql_create_astronauts_table)
        add_astronauts_bulk(ASTRONAUTS)
    else:
        message = "Cannot create database connection!"
        LOG.error(message)
        raise Exception(message)

    conn.close()
Example #12
0
def validate_token(req, resp, resource, params):
    LOG.debug('JWT Validation')
    token = req.get_header('Authorization')

    if token is None:
        error = {
            "description": "Please provide JWT token as part of the request."
        }
        raise generic_error_handler(401, error_override=error)

    try:
        token_is_valid(req, token)
    except Exception as ex:
        error = {"description": "invalid token, try again", "details": str(ex)}
        raise generic_error_handler(401, error_override=error)
Example #13
0
def token_is_valid(req, token):
    if token.startswith("JWT "):
        token_type = "JWT"
    else:
        LOG.error("Token validation failed")
        raise Exception("Invalid token type -> Only 'JWT' allowed")

    req.jwt_token = token
    token = token.split(f"{token_type} ")[1]

    try:
        jwt_body = jwt.decode(token,
                              API_SECRET_KEY,
                              verify=True,
                              algorithms=['HS256'])
        if 'username' in jwt_body:
            req.username = jwt_body['username']
    except Exception as ex:
        LOG.error(f"There was an error : {ex}")
        raise Exception(f"{ex}")
Example #14
0
    def on_post(self, req, res):
        username = req.get_json('username', dtype=str)
        password = req.get_json('password', dtype=str)

        users = db.fetch_users(username)
        if len(users) == 1:
            if not checking_password_hash(password, users[0]['password']):
                error = {
                    'description': 'either username or password is invalid'
                }
                LOG.error(error)
                raise generic_error_handler(401, req=req, error_override=error)
            else:
                payload = OrderedDict()
                payload['id'] = users[0]['id']
                payload['username'] = username

                data = jwt_payload_handler(payload)

                payload = {**payload, **data}

                self.on_success(res, payload)

        elif len(users) > 1:
            error = {
                'description':
                f"There was more than 1 user found for username: '******'"
            }
            LOG.error(error)
            raise generic_error_handler(401, req=req, error_override=error)

        else:
            error = {'description': 'either username or password is invalid'}
            LOG.error(error)
            raise generic_error_handler(401, req=req, error_override=error)
Example #15
0
    def on_patch(self, req, res, id_):
        params = {'id_': id_}
        astronauts = db.fetch_astronauts(filters=params)
        if astronauts:
            data = astronauts[0]

            payload = OrderedDict()
            payload["active"] = req.get_json("active", default=data['active'])
            payload["firstName"] = req.get_json("firstName",
                                                default=data['firstName'])
            payload["lastName"] = req.get_json("lastName",
                                               default=data['lastName'])
            skills = req.get_json("skills", default=data['skills'])
            if not isinstance(skills, list):
                error = {
                    'description': 'invalid skills',
                    'details': f"'skills' field needs to be an array/list"
                }
                LOG.error(error)
                raise generic_error_handler(400, req=req, error_override=error)
            payload["skills"] = skills
            payload["hoursInSpace"] = req.get_json(
                "hoursInSpace", default=data['hoursInSpace'])
            payload["picture"] = req.get_json("picture",
                                              default=data['picture'])

            db.update_astronaut_info(id_, fields=payload)

        else:
            error = {
                'description': 'Invalid astronaut',
                'details': f"An astronaut with id '{id_}' doesn't exist."
            }
            LOG.error(error)
            raise generic_error_handler(404, req=req, error_override=error)

        payload = {**{'id': id_}, **payload}

        self.on_success(res, payload)
Example #16
0
    def __init__(self, *args, **kwargs):
        super(App, self).__init__(*args, **kwargs)
        LOG.info(f'Starting {APP_NAME}')
        self.add_route('/', base.BaseResource())
        
        # Users
        self.add_route('/api/users', users.Users())
        self.add_route('/api/users/{user_id}', users.Users())

        # Credentials to get JWT
        self.add_route('/api/credentials', users.JWTLogin())
        
        # Astronauts
        self.add_route('/api/astronauts', astronauts.List())
        self.add_route('/api/astronauts/{id_}', astronauts.Detail())

        # This catches none existing paths
        self.add_sink(generic_path_error_handler, '')

        # This is needed starting in Falcon 2.0 (where the default value changed
        # from `True` to `False`).
        self.req_options.strip_url_path_trailing_slash = True
Example #17
0
    def on_delete(self, req, res, id_):
        params = {'id_': id_}
        astronauts = db.fetch_astronauts(filters=params)
        if astronauts:
            data = astronauts[0]
            astronaut_id = astronauts[0]['id']
            db.delete_from_table('astronauts', astronaut_id)

        else:
            error = {
                'description': 'Invalid astronaut',
                'details': f"An astronaut with id '{id_}' doesn't exist."
            }
            LOG.error(error)
            raise generic_error_handler(404, req=req, error_override=error)
        if req.params.get('details') == 'true':
            data['meta'] = {
                'action':
                f'astronaut {astronauts[0]["firstName"]} {astronauts[0]["lastName"]} has been deleted'
            }
            self.on_success(res, data)
        else:
            self.on_no_content(res, {})
Example #18
0
def add_astronauts_bulk(astronauts):
    conn = create_connection(DATABASE)
    c = conn.cursor()
    for astronaut in astronauts:
        skills = ",".join(astronaut["skills"])
        try:
            c.execute(f"""INSERT INTO astronauts (
                    id_, active, firstName, lastName, skills, hoursInSpace, picture)
                    VALUES (
                    '{astronaut["id"]}',
                    '{astronaut["active"]}',
                    '{astronaut["firstName"]}',
                    '{astronaut["lastName"]}',
                    '{skills}',
                    '{astronaut["hoursInSpace"]}',
                    '{astronaut["picture"]}');""")
        except sqlite3.IntegrityError as ex:
            conn.close()
            LOG.error(ex)
            raise Exception(
                f"{ex} when processing: {astronaut['firstName']} {astronaut['lastName']}"
            )
    conn.commit()
    conn.close()
Example #19
0
    def on_patch(self, req, res):
        username = req.get_json('username', dtype=str, min=3, max=20)
        password = req.get_json('password', dtype=str, min=8, max=20)
        new_password = req.get_json('new_password', dtype=str, min=8, max=20)

        pasword = make_password_hashing(new_password)
        
        users = db.fetch_users(username)

        if len(users) == 1:
            if not checking_password_hash(password, users[0]['password']):
                error = {
                    'description': 'Incorrect password entered',
                }
                LOG.error(error)
                raise generic_error_handler(401, req=req, error_override=error)
            else:
                db.update_password(users[0]['id'], pasword)
                data = {
                    'id': users[0]['id'],
                    'username': username
                }

                self.on_success(res, data)

        elif len(users) > 1:
            error = {
                'description': f"There was more than 1 user found for username: '******'"
            }
            LOG.error(error)
            raise generic_error_handler(400, req=req, error_override=error)

        else:
            error = {
                'description': 'Invalid username',
                'details': f"{username} doesn't exist."
            }
            LOG.error(error)
            raise generic_error_handler(404, req=req, error_override=error)