Beispiel #1
0
def v1_register():
    """ Add new user into profiles table
    3 GET params (all srt):
        login
        password => password (sha256 in db)
        name
    Returns:
        200 = login
        400 = Missing params/Login taken/Invalid name
        500 = ???
    """
    if 'login' not in request.query or 'password' not in request.query or 'name' not in request.query:
        response.status = 400
        return json.dumps({
            'status':
            '400',
            'error':
            'Missing GET params, 3 needed (login, password, name).'
        })

    if len(request.query.name) < 3:
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Name must consist at least 3 chars.'
        })

    if not all(x.isalpha() or x.isspace() for x in request.query.name):
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Name must consist only of letters.'
        })

    login = request.query.login

    select_query = "SELECT id FROM profiles WHERE login='******'".format(login)

    if exec_sql(select_query)[0] == 0:  # In case such login not found
        # password in db is sha256 hash
        pass_sha256 = hashlib.sha256(
            request.query.password.encode()).hexdigest()
        insert_query = "INSERT INTO profiles (login, password, profile_name) VALUES ('{0}', '{1}', '{2}')"\
            .format(login, pass_sha256, request.query.name)
        if exec_sql(insert_query)[0] == 1:
            return json.dumps({'status': '200', 'login': login})
        else:
            response.status = 500
            return json.dumps({
                'status':
                '500',
                'error':
                'Too much affected rows, during insertion of new user.'
            })
    else:  # In case login already exists in db
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Login is already taken.'
        })
Beispiel #2
0
 def resolve_user(self, info, id):
     # Check if user exists
     if mysql_query.exec_sql(
             "SELECT * FROM profiles WHERE id={}".format(id))[0]:
         return User(id=id)
     else:
         print('There are no user in db with id = ' + str(id))
         return None
Beispiel #3
0
def v1_add_note():
    if 'api_key' not in request.query:
        response.status = 401
        return json.dumps({
            'status': '401',
            'error': 'This method requires authentication.'
        })

    if 'content' not in request.query:
        response.status = 400
        return json.dumps({'status': '400', 'error': 'Empty note.'})
    elif request.query.content.strip() == '':
        response.status = 400
        return json.dumps({'status': '400', 'error': 'Empty note.'})

    db_profile_info = exec_sql(
        "SELECT id FROM profiles WHERE api_key='{}'".format(
            request.query.api_key))

    if db_profile_info[0] == 1:  # Case 'api_key is ok'
        user_id = db_profile_info[1][0]['id']
        insert_query = exec_sql(
            "INSERT INTO notes (content, user_id) VALUES ('{}', {})".format(
                request.query.content, user_id))
        if insert_query[0] == 1:
            return json.dumps({'status': '200'})
        else:
            response.status = 500
            return json.dumps({
                'status':
                '500',
                'error':
                'Too much affected rows, during insertion of note.'
            })
    elif db_profile_info[0] == 0:
        response.status = 401
        return json.dumps({'status': '401', 'error': 'Wrong api_key.'})
    else:
        response.status = 500
        return json.dumps({
            'status': '500',
            'error': 'Found few profiles with given api_key.'
        })
Beispiel #4
0
def v2_upload_profile_image():
    """ Upload image from clients device and mark it as profile photo, delete old image
        1 GET param:
            api_key
        Returns:
            200 = deleted old image, new image is on server and updated path to file in db
            400 = Wrong file type
            401 = Missing api_key or it's wrong
            500 = Duplicate profiles/Error while upload/Error while updating db
        """
    if 'api_key' not in request.query:
        response.status = 401
        return json.dumps({
            'status': '401',
            'error': 'This method requires authentication.'
        })

    db_profile_info = exec_sql(
        "SELECT * FROM profiles WHERE api_key='{}'".format(
            request.query.api_key))
    if db_profile_info[0] == 1:  # Case 'api_key is ok'
        old_file_path = db_profile_info[1][0]['profile_photo_url']
        if old_file_path:
            os.rename(old_file_path, old_file_path + '.backup')

        # Restore image from backup in case of error
        def restore_img():
            if old_file_path:
                os.rename(old_file_path + '.backup', old_file_path)

        # Suitable for storage name for image and path to directory with images
        file_name = str(db_profile_info[1][0]["id"]) + "_avatar"
        file_path = "content"
        # Correct path to future file
        download_image_path = os.path.join(file_path, file_name)

        if request.body:
            try:
                with open(download_image_path, 'wb') as file:
                    file.write(request.body.getvalue())
                file.close()
                file_ext = str(imghdr.what(download_image_path))
                if file_ext == 'None':
                    restore_img()
                    response.status = 400
                    return json.dumps({
                        'status':
                        '400',
                        'error':
                        'Looks like given file is not image'
                    })
                file_full_path = str(
                    os.path.join(file_path, file_name + "." + file_ext))
                # Give file extension corresponding to it's type
                os.rename(download_image_path,
                          os.path.join(file_path, file_name + "." + file_ext))
                # Record new path to image into db
                update_query = exec_sql(
                    "UPDATE profiles SET profile_photo_url='{0}' WHERE api_key='{1}'"
                    .format(file_full_path, request.query.api_key))
                if update_query[0] == 1 or file_full_path == old_file_path:
                    # As new image successfully downloaded and it's path recorded in db, old one can be deleted
                    os.remove(old_file_path + '.backup')
                    return json.dumps({'status': '200'})
                else:
                    restore_img()
                    response.status = 500
                    return json.dumps({
                        'status':
                        '500',
                        'error':
                        'Some error while updating image path in db.'
                    })
            except:
                restore_img()
                response.status = 500
                return json.dumps({
                    'status': '500',
                    'error': 'Error during downloading file.'
                })
        else:
            restore_img()
            response.status = 400
            return json.dumps({'status': '400', 'error': 'Empty file.'})
    elif db_profile_info[0] == 0:  # Case 'Wrong api_key'
        response.status = 401
        return json.dumps({'status': '401', 'error': 'Wrong api_key.'})
    else:  # Case 'Duplicate profiles'
        response.status = 500
        return json.dumps({
            'status': '500',
            'error': 'Found few profiles with given api_key.'
        })
Beispiel #5
0
def v1_auth():
    """ Generate new api key, register it in db and give to client
    2 GET params (both str):
        login
        password
    Returns JSON:
        200 = api_key + api_key in HTTP-header "Authentication"
        400 = Missing params/Wrong auth data
        500 = Duplicate profiles/Error during insertion api_key
    """
    if 'login' not in request.query or 'password' not in request.query:
        response.status = 400
        return json.dumps({
            'status':
            '400',
            'error':
            'Missing GET params, 2 needed (login, password).'
        })

    login = request.query.login
    password = request.query.password

    db_pass_tuple = exec_sql("SELECT password FROM profiles WHERE login='******'")
    db_pass_count = db_pass_tuple[0]
    db_pass = db_pass_tuple[1][0]["password"]

    if db_pass_count == 0:  # Case 'not found'
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Wrong login or password given.'
        })
    elif db_pass_count > 1:  # Case 'duplicates' (anomaly)
        response.status = 500
        return json.dumps({
            'status': '500',
            'error': 'Found few profiles with given login.'
        })
    elif db_pass_count == 1:  # Case 'OK, found account with given login'
        if db_pass == hashlib.sha256(
                password.encode()).hexdigest():  # If passwords match
            # Generate api_key and then write it into db
            api_key = hashlib.sha256(
                (str(datetime.datetime.now()) + login).encode()).hexdigest()
            insert_query = exec_sql(
                "UPDATE profiles SET api_key='{}' WHERE login = '******'".format(
                    api_key, login))

            if insert_query[0] == 1:
                response.add_header("Authentication", api_key)
                return json.dumps({'status': '200', 'api_key': api_key})
            else:
                response.status = 500
                return json.dumps({
                    'status':
                    '500',
                    'error':
                    'Something went wrong during insertion api_key into db.'
                })
        else:  # Case 'wrong password'
            response.status = 400
            return json.dumps({
                'status': '400',
                'error': 'Wrong login or password given.'
            })
Beispiel #6
0
def v1_get_profile_data():
    """ Fetch data about user profile by given id. If id is not given - fetch own data
        Data: profile_name, photo_file_url, date_of_registration
    2 GET params:
        api_key
        profile_id - optional
    Returns:
        200 = Own or found by id data
        400 = Given id, but profile not found
        401 = Missing or wrong api_key
        500 = Duplicate profiles
    """

    if 'api_key' not in request.query:
        response.status = 401
        return json.dumps({
            'status': '401',
            'error': 'This method requires authentication.'
        })

    db_profile_info = exec_sql(
        "SELECT * FROM profiles WHERE api_key='{}'".format(
            request.query.api_key))

    if db_profile_info[0] == 1:  # Case 'api_key is ok'
        if 'profile_id' not in request.query or request.query.profile_id.strip(
        ) == '':
            # Case 'profile_id is not given' - fetch own data
            profile_data = db_profile_info[1][0]
            json_report = json.dumps({
                'status': '200',
                'data': {
                    'profile_name':
                    profile_data['profile_name'],
                    'profile_photo_url':
                    profile_data['profile_photo_url'],
                    'date_of_registration':
                    str(profile_data['date_of_registration'])
                }
            })
            return json_report
        else:  # Case 'profile_id is given'
            db_profile_info = exec_sql("SELECT * FROM profiles WHERE id=" +
                                       request.query.profile_id)
            if db_profile_info[0] == 1:  # Case 'profile with given id found'
                profile_data = db_profile_info[1][0]
                json_report = json.dumps({
                    'status': '200',
                    'data': {
                        'profile_name':
                        profile_data['profile_name'],
                        'profile_photo_url':
                        profile_data['profile_photo_url'],
                        'date_of_registration':
                        str(profile_data['date_of_registration'])
                    }
                })
                return json_report
            elif db_profile_info[0] == 0:  # Case 'id is wrong'
                response.status = 400
                return json.dumps({
                    'status': '400',
                    'error': 'Profile with given id not found.'
                })
            else:
                response.status = 500
                return json.dumps({
                    'status':
                    '500',
                    'error':
                    'Found few profiles with given profile_id.'
                })
    elif db_profile_info[0] == 0:
        response.status = 401
        return json.dumps({'status': '401', 'error': 'Wrong api_key.'})
    else:
        response.status = 500
        return json.dumps({
            'status': '500',
            'error': 'Found few profiles with given api_key.'
        })
Beispiel #7
0
def v1_change_profile_name():
    """ Change profile_name for authenticated client
    2 GET params:
        api_key
        new_name
    Returns:
        200 = profile_name(new_name)
        400 = Missing new_name/Invalid name
        401 = Missing api_key or it's wrong
        500 = Duplicate profiles/Troubles with update query
    """
    if 'api_key' not in request.query:
        response.status = 401
        return json.dumps({
            'status': '401',
            'error': 'This method requires authentication.'
        })

    if 'new_name' not in request.query:
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Missing new_name param.'
        })

    if len(request.query.new_name) < 3:
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Name must consist at least 3 chars.'
        })

    if not all(x.isalpha() or x.isspace() for x in request.query.new_name):
        response.status = 400
        return json.dumps({
            'status': '400',
            'error': 'Name must consist only of letters.'
        })

    db_profile_info = exec_sql(
        "SELECT * FROM profiles WHERE api_key='{}'".format(
            request.query.api_key))
    if db_profile_info[0] == 1:  # Case 'api_key is okay'
        update_query = exec_sql(
            "UPDATE profiles SET profile_name='{}' WHERE api_key='{}'".format(
                request.query.new_name, request.query.api_key))
        if update_query[0] == 1 or db_profile_info[1][0][
                'profile_name'] == request.query.new_name:
            return json.dumps({
                'status': '200',
                'profile_name': request.query.new_name
            })
        else:
            response.status = 500
            return json.dumps({
                'status':
                '500',
                'error':
                'Something went wrong during updating profile_name in db.'
            })

    elif db_profile_info[0] == 0:  # Case 'api key is wrong'
        response.status = 401
        return json.dumps({'status': '401', 'error': 'Wrong api_key.'})
    else:  # Case 'duplicates'
        response.status = 500
        return json.dumps({
            'status': '500',
            'error': 'Found few profiles with given api_key.'
        })
Beispiel #8
0
 def resolve_notes(self, info):
     db_notes = mysql_query.exec_sql(
         "SELECT content, date FROM notes WHERE user_id={}".format(
             self.id))[1]
     return [Note(date=x['date'], content=x['content']) for x in db_notes]
Beispiel #9
0
 def resolve_name(self, info):
     return mysql_query.exec_sql(
         "SELECT profile_name FROM profiles WHERE id={}".format(
             self.id))[1][0]['profile_name']