def address():
    """Get the address of a certain user.

    From the users and servers tables, necessary details are extracted from
    entries containing the given username.

    Returns:
        JSON response containing the address details of a certain user.
        If the user is not found or the server is non existant, a failed JSON
        response is returned.
    """
    username = request.args.get('username')

    # If username is not given, use the logged in username.
    if username is None or username == '':
        username = auth_username()

    if username is None or username == '':
        return bad_json_response("Bad request: Missing parameter 'username'.")

    if users.exists(username=username):
        server_id = users.export_one('server_id', username=username)

        if not servers.exists(id=server_id):
            bad_json_response('Server is not registered.')

        name, address = servers.export_one('name', 'address', id=server_id)
        return good_json_response({
            'name': name,
            'address': address,
            'username': username
        })
    else:
        return bad_json_response('User is not found.')
def user_posts():
    """Retrieve all posts from a certain username.

    Checks are in place to check if the user is indeed a member of FedNet.
    This function uses the get_posts function below to actually retrieve the
    posts.

    Returns:
        JSON response that contains all posts of a certain user.
    """
    username = request.args.get('username')

    if username is None or username == '':
        username = auth_username()

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")

    # Check if user id exists.
    if not users.exists(username=username):
        return bad_json_response('User not found.')

    # Send no data in case the users are not friends.
    if username != get_jwt_identity() and is_friend(username) != 1:
        return good_json_response({'posts': {}})

    return good_json_response({
        'posts': get_posts(username)
    })
def register():
    """Register a user to the central server.

    For this registration, the username and server address are requested in the
    form. A check is performed to see if the server is live. Then the user is
    inserted into the users table.

    Returns:
        Success JSON response if the operation is successful.
        If the username is valid or the server is not live, a failed JSON
        response is returned.
    """
    username = request.form['username']
    address = request.form['server_address']

    if not servers.exists(address=address):
        return bad_json_response('Server is not registered.')

    server_id = servers.export_one('id', address=address)

    if ping(address):
        if not users.exists(username=username):
            users.insert(username=username, server_id=server_id)
        else:
            return bad_json_response(
                'Username is already taken. Try again :).')
    else:
        return bad_json_response('This data server is not available. '
                                 'Please contact the server owner.')

    return good_json_response('success')
def edit():
    """Edit a certain users details in the central server.

    The entry with the certain users username is edited in the users table in
    the database.

    Returns:
        Success JSON response if the operation is successful.
        Else a failed JSON response is returned with the correct error message.
    """
    username = get_jwt_identity()

    if users.exists(username=username):
        if 'new_address' in request.form:
            new_address = request.form['new_address']
            if 'new_address' != '':
                if servers.exists(address=new_address):
                    new_id = servers.export_one('id', address=new_address)
                    users.update({'server_id': new_id}, username=username)
                    return good_json_response({'new_address': new_address})
                else:
                    return bad_json_response(
                        'This address does not exist in the database.')
            else:
                return bad_json_response('Address undefined.')
        else:
            return bad_json_response('Incorrect form.')
    else:
        return bad_json_response('No user found with the username ' +
                                 username + '.')
Exemple #5
0
def delete():
    """Delete a post.

    For a post to be deleted, the post ID is requested in the form. The post
    entry corresponding to the given post ID is then deleted from the posts
    table.

    Returns:
        Success JSON response if the operation succeeded.
        Else a failed JSON response is returned with the correct error message.
    """
    username = get_jwt_identity()
    post_id = request.form['post_id']

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")
    if post_id is None:
        return bad_json_response("Bad request: Missing parameter 'post_id'.")

    if not users.exists(username=username):
        return bad_json_response('User not found')

    if not posts.exists(id=post_id):
        return bad_json_response('Post not found')

    # Check if the user is the post owner.
    post_username = posts.export_one('username', id=post_id)
    if post_username != username:
        return bad_json_response('Not your post')

    # Delete post.
    posts.delete(id=post_id)

    return good_json_response('success')
def send_verification_mail():
    """Handles the sending of verification email.

    Returns:
        JSON response based on succes/failure.
    """
    # Check if parameter email is set.
    send_to = request.form['email']
    if not send_to:
        return bad_json_response("Bad request: Missing parameter 'email'.")

    # Retrieve user from server for personal message in email.
    user = users.export_one('firstname', 'lastname',
                            email=request.form['email'])

    # If no user is found give an error.
    if not user:
        return bad_json_response('Error retrieving the user.')

    # Construct message object with receipient and sender
    msg = EmailMessage()
    msg['Subject'] = 'FedNet - Please verify your email!'
    msg['From'] = current_app.config['EMAIL_ADDRESS']
    msg['To'] = send_to

    # Create the secret key based on our little secret :)
    secret = URLSafeTimedSerializer(current_app.config['EMAIL_SECRET'])

    # Create token based on a user their email and salt to prevent same token.
    token = secret.dumps(send_to,
                         salt=current_app.config['EMAIL_REGISTER_SALT'])

    # Create link with token and add it to the body of the mail.
    link = url_for('data_mail.confirm_email', token=token, _external=True)

    # Load the HTML template for the email, and embed the information needed.
    with open('app/templates/email_template/verify-mail.html') as f:
        html = f.read()
    html = html.replace('VERIFY_LINK_HERE', link)
    html = html.replace('USERNAME_HERE', user[0] + ' ' + user[1])
    msg.add_alternative(html, subtype='html')

    # Add image to the contents of the email.
    with open('app/static/images/LogoBackOpaque.png', 'rb') as img:
        # Know the Content-Type of the image.
        maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')

        # Attach it to the email. The cid='0' is linked to the cid in the html,
        # which loads it.
        msg.get_payload()[0].add_related(img.read(), maintype=maintype,
                                         subtype=subtype, cid='0')

    # Connect to the mailserver from google and send the e-mail.
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(current_app.config['EMAIL_ADDRESS'],
                   current_app.config['EMAIL_PASSWORD'])
        smtp.send_message(msg)

    return good_json_response('success')
def forgot_username():
    """Sends email to reset username.

    Returns:
        JSON reponse based on succes/failure.
    """
    email = request.form['email']

    if not email:
        return bad_json_response("Bad request: Missing parameter 'email'.")

    # Retrieve email for given username.
    # Also retrieve firstname and lastname for personal message.
    username = users.export_one('username', email=email)

    # If no user is found for given email, don't send email.
    if not username:
        return bad_json_response(
            'No user with this e-mail exists on this server: ' + get_own_ip()
        )

    # Construct message object with receipient and sender.
    msg = EmailMessage()
    msg['Subject'] = 'FedNet - Your username is ' + username
    msg['From'] = current_app.config['EMAIL_ADDRESS']
    msg['To'] = email

    # Load the HTML template for the email, and embed the information needed.
    with open('app/templates/email_template/forgot-username.html') as f:
        html = f.read()
    html = html.replace('USERNAME_HERE', username)
    msg.add_alternative(html, subtype='html')

    # Add image to the contents of the email.
    with open('app/static/images/LogoBackOpaque.png', 'rb') as img:
        # Know the Content-Type of the image
        maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')

        # Attach it to the email. The cid='0' is linked to the cid in the html,
        # which loads it.
        msg.get_payload()[0].add_related(img.read(), maintype=maintype,
                                         subtype=subtype, cid='0')
    # Connect to the mailserver from google and send the e-mail.
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(current_app.config['EMAIL_ADDRESS'],
                   current_app.config['EMAIL_PASSWORD'])
        smtp.send_message(msg)

    return good_json_response(('Email was sent to ' + email + '.'))
def get_pub_key(username):
    """Helper function to get the public key of a user.
    
    Returns:
        The public key of a user if available, else a bad JSON response.
    """
    server_id = users.export_one('server_id', username=username)
    if server_id is None:
        return bad_json_response('No server_id')

    pub = servers.export_one('pub_key', id=server_id)
    if pub is None:
        return bad_json_response('No pub')

    return pub
def hobby():
    """Get all hobby details from a certain user.

    Returns:
        JSON reponse with the hobby details from the hobbies table.
    """
    username = request.args.get('username')

    if username is None or username == '':
        username = auth_username()

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")

    # Extract all the needed data from the hobbies table in the database.
    hobbies_details = hobbies.export('id', 'title', username=username)

    hobbies_array = [
        {
            'id': item[0],
            'title': item[1]
        }
        for item in hobbies_details
    ]

    return good_json_response({
        'hobbies': hobbies_array
    })
def language():
    """Get all language details from a certain user.

    Returns:
        JSON reponse with the language details from the languages table.
    """
    username = request.args.get('username')

    if username is None or username == '':
        username = auth_username()

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")

    # Extract all the needed data from the language table in the database.
    language_details = languages.export('id', 'title', 'skill_level',
                                        username=username)

    language_array = [
        {
            'id': item[0],
            'title': item[1],
            'skill_level': item[2]
        }
        for item in language_details
    ]

    return good_json_response({
        'languages': language_array
    })
Exemple #11
0
def post():
    """Get all the necessary details for a post.

    The post ID is checked to see if the post actually exists. The same is done
    with the upload ID.

    Returns:
        JSON response with the post details.
    """
    post_id = request.args.get('post_id')

    if post_id is None:
        return bad_json_response('post_id should be given as parameter.')

    post_db = posts.export('id', id=post_id)
    if not post_db:
        return bad_json_response('post not found')

    post_db = posts.export('body',
                           'title',
                           'username',
                           'uploads_id',
                           'creation_date',
                           'last_edit_date',
                           id=post_id)[0]

    # Get image.
    up_id = post_db[3]

    if uploads.exists(id=up_id):
        filename = uploads.export_one('filename', id=up_id)
        imageurl = get_own_ip() + 'file/{}/{}'.format(up_id, filename)

    return good_json_response({
        'post_id': post_id,
        'body': post_db[0],
        'title': post_db[1],
        'username': post_db[2],
        'profile_image': get_profile_image(post_db[2]),
        'image_url': imageurl,
        'creation_date': str(post_db[4]),
        'last_edit_date': str(post_db[5])
    })
def login():
    """Function that handles the login.

    An access token is created. A check is in place to verify the encrypted
    password and to check if the user is verified through e-mail.

    Returns:
        A success JSON reponse that contains the access token.
    """
    username = request.form['username']
    password = request.form['password']

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")

    if password is None:
        return bad_json_response("Bad request: Missing parameter 'password'.")

    if not users.exists(username=username):
        return bad_json_response(
            "User does not exist yet. Feel 'free' to join FedNet! :)"
        )

    password_db = users.export('password', username=username)[0]

    # Verify the given password.
    if not sha256_crypt.verify(password, password_db):
        return bad_json_response('Password is incorrect.')

    # Check if the account has been verified through e-mail.
    email_confirmed = users.export_one('email_confirmed', username=username)
    if not email_confirmed:
        return bad_json_response(
            'The email for this user is not authenticated yet. '
            'Please check your email.'
        )

    # Login success.
    access_token = create_access_token(identity=username)

    return good_json_response({
        'token': access_token
    })
def timeline():
    """This function handles the timeline, making sure you only see posts from
    the correct people.

    If you are friends with a certain user, that users posts will be shown in
    your timeline.

    Imported:
        get_friends function from api/data/friend.py

    Returns:
        JSON reponse that contains all the posts that are shown in the timeline.
    """
    from app.api.data.friend import get_friends

    username = get_jwt_identity()
    # Check if user exists.
    if not users.exists(username=username):
        return bad_json_response('user not found')

    # Get the user's own posts.
    posts_array = get_posts(username)

    # Get the user's friends.
    friends = get_friends(username)

    for i in range(len(friends)):
        try:
            friend = friends[i]['username']
            friend_address = get_user_ip(friend)
            # Get the posts of the friend.
            response = requests.get(
                friend_address + '/api/user/posts',
                params={
                    'username': friend
                },
                headers=request.headers
            ).json()
            if response['success']:
                posts = response['data']['posts']
                posts_array = posts_array + posts
        except BaseException:
            continue

    posts_array = sorted(
        posts_array,
        key=lambda k: datetime.datetime.strptime(k['creation_date'],
                                                 '%Y-%m-%d %H:%M:%S'),
        reverse=True
    )

    return good_json_response({
        'posts': posts_array
    })
Exemple #14
0
def create():
    """Create a new post.

    For a post to be created, details are submitted in the form. These details
    are then inserted into the posts table in the database.

    Returns:
        Success JSON response if the operation succeeded.
        Else a failed JSON response is returned with the correct error message.
    """
    username = get_jwt_identity()
    title = request.form['title']
    body = request.form['body']

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")
    if title is None:
        return bad_json_response("Bad request: Missing parameter 'title'.")
    if body is None:
        return bad_json_response("Bad request: Missing parameter 'body'.")

    if not users.exists(username=username):
        return bad_json_response('User not found.')

    # Insert post.
    if 'file' in request.files:
        image_filename = request.files['file'].filename
        image = request.files['file'].read()

        if image is not 0:
            uploads_id = save_file(image, filename=image_filename)

            if uploads_id is not False:
                posts.insert(username=username,
                             body=body,
                             title=title,
                             uploads_id=uploads_id)
            else:
                posts.insert(username=username, body=body, title=title)

    return good_json_response('success')
def pub_key():
    """Get the public key of a user.
    
    Returns:
        JSON response containing the public key of a user.
    """
    username = request.args.get('username')

    if username is None:
        return bad_json_response('No username')

    return good_json_response(get_pub_key(username))
def forgotpassword():
    username = request.form['username']
    password = request.form['password']

    if password is None:
        return bad_json_response("Bad request: Missing parameter 'password'.")

    new_password = sha256_crypt.encrypt(request.form['password'])

    users.update({'password': new_password}, username=username)

    return good_json_response('Succes')
def user():
    """Get all usernames and their respective server ID's from the users table.

    Returns:
        JSON response containing all the usernames in the users table.
    """
    usernames = users.export('username', 'server_id')

    if len(usernames) == 0:
        return bad_json_response('No usernames in the database.')

    return good_json_response({'usernames': usernames})
Exemple #18
0
def get_comments():
    """Get all comments from a certain post.

    To retrieve all comments on a certain post, the post ID is requested in the
    form. All the comment entries in the comments table corresponding to the
    given post ID are then retrieved.

    Returns:
        JSON response containing a list with all the comments if the operation
        succeeded.
        Else a failed JSON response is returned with the correct error message.
    """
    post_id = request.args.get('post_id')

    if post_id is None or post_id == '':
        return bad_json_response(
            "Bad request: Missing or invalid parameter 'post_id'.")

    if not posts.exists(id=post_id):
        return bad_json_response('Post id does not exist.')

    comment_details = comments.export('id',
                                      'comment',
                                      'username',
                                      'creation_date',
                                      'last_edit_date',
                                      post_id=post_id)

    comments_array = [{
        'id': item[0],
        'comment': item[1],
        'username': item[2],
        'profile_image': get_profile_image(item[2]),
        'creation_date': str(item[3]),
        'last_edit_date': str(item[4])
    } for item in comment_details]

    return good_json_response({'comments': comments_array})
def register():
    """Register a data server to the central server.

    For this registration, the server name and address are requested in the
    form. A check is performed to see if the server is live. Then the server
    is inserted into the servers table if it does not already exists.
    
    Returns:
        JSON response containing the server id and the public key
        at success, else a bad JSON response containing the error message.
    """
    name = request.form['name']
    address = request.form['address']

    pub_key = ping(address)
    if pub_key:
        if not servers.exists(address=address):
            result = servers.insert(
                name=name, address=address, pub_key=pub_key)
            return good_json_response({
                'server_id': result,
                'pub_key': pub_key
            })
        else:
            name = servers.export_one('name', address=address)
            return bad_json_response(
                'The data server at "'
                + address
                + '" is already registered by the name "'
                + name
                + '".'
            )
    else:
        return bad_json_response(
            'The data server at "'
            + address +
            '" did not respond. Is the installation correct?'
        )
def password():
    """Upon entering the old password, a new password can be set.

    The old password is verified and the new password is encrypted and updated
    in the database.
    """
    username = get_jwt_identity()
    password = request.form['oldPassword']

    if password is None:
        return bad_json_response("Bad request: Missing parameter 'password'.")

    password_db = users.export('password', username=username)[0]

    if not sha256_crypt.verify(password, password_db):
        return bad_json_response('Password is incorrect.')

    if 'newPassword' in request.form:
        new_password = sha256_crypt.encrypt(request.form['newPassword'])
    if 'newPassword' != '':
        users.update({'password': new_password}, username=username)

    return good_json_response('Succes')
def users_all():
    """Get all usernames in the users table.

    Returns:
        JSON reponse that contains all the usernames in the users table.
    """
    usernames = users.export('username')

    if len(usernames) == 0:
        return bad_json_response('No users found.')

    return good_json_response({
        'usernames': usernames
    })
Exemple #22
0
def search():
    """Searches for existing usernames.

    Returns:
        JSON reponse based on failure/succes.
    """
    input_data = request.form['search_input']

    if users.exists(username=username):
        return bad_json_response('Username is already registered.')

    users.insert(username=username, location=location, study=study)

    return good_json_response('success')
def delete():
    """Delete a user from FedNet.

    The users details in the users table are deleted.
    """
    username = get_jwt_identity()

    if users.exists(username=username):
        # Everything that belongs to user is deleted automatically.
        users.delete(username=username)

        return good_json_response({'user': username})
    else:
        return bad_json_response('Username is not registered.')
def export_zip_():
    """Export all the data of a certain user as a zip.

    Returns:
        If the user exists, the user details will be exported.
    """

    username = get_jwt_identity()

    if users.exists(username=username):
        return send_file(export_zip(username), mimetype='application/zip',
                         as_attachment=True, attachment_filename='export.zip')
    else:
        return bad_json_response('User does not exist in database.')
def registered():
    """Look up if the given username is a registered username in FedNet.

    Returns:
        JSON reponse that succeeds if the username is registered and
        fails if the user is not registered.
    """
    username = request.args.get('username')

    if username is None:
        return bad_json_response("Bad request: Missing parameter 'username'.")

    if not users.exists(username=username):
        return bad_json_response('Username not found (in data server)')

    # This request checks if the given username is registered.
    r = requests.get(
        get_central_ip() + '/api/user/registered',
        params={
            'username': username
        }
    ).json()

    return good_json_response(r)
def register():
    """Registers a user to this data server.

    All the given information is stored in the users table in the database.
    """
    # Exit early.
    if users.exists(username=request.form['username']):
        return bad_json_response('Username is already taken. Try again :)')

    if users.exists(email=request.form['email']):
        return bad_json_response(
            'A user with this email is already registered on this data server.'
        )

    username = request.form['username']
    firstname = request.form['firstname']
    lastname = request.form['lastname']
    email = request.form['email']
    password = sha256_crypt.encrypt(request.form['password'])

    users.insert(username=username, firstname=firstname, lastname=lastname,
                 password=password, email=email)

    return good_json_response('success')
def import_zip_():
    """Import all the data of a certain user.

    Returns:
        Success JSON response in case the import was successful.
        Else the bad JSON response will be returned with an error message.
    """
    username = get_jwt_identity()

    if 'file' in request.files:
        file = request.files['file'].read()
        if file is not 0:
            import_zip(file, username=username)
            return good_json_response()
    return bad_json_response('File not received.')
Exemple #28
0
def file_main():
    """Function that handles getting a file.

    Returns:
        A bad JSON response if file is not found.
        A good JSON response with file URL if file is found successfully
    """
    file_id = request.args.get('id')

    if not uploads.exists(id=file_id):
        return bad_json_response('File ID does not exist.')

    filename = uploads.export_one('filename', id=file_id)

    return good_json_response({'url': '/file/{}/{}'.format(file_id, filename)})
def get_key():
    """Function for getting the public key.

    Returns:
        JSON reponse with either public key on success or error message on
        failure.
    """
    with open('jwtRS256.key.pub') as f:
        pub_key = f.read()

    if pub_key is not None:
        return good_json_response(pub_key)
    else:
        return bad_json_response(
            'Error retrieving the public key of server: ' + get_own_ip())
def registered():
    """Check if a certain user is registered in the users table.

    Returns:
        JSON response containing username of the certain user if the user is
        indeed registered.
        If the username is not found, a failed JSON response is returned.
    """
    username = request.args.get('username')

    if username is None:
        return bad_json_response('Username should be given as parameter.')

    exists = users.exists(username=username)

    return good_json_response({'registered': exists})