Exemplo n.º 1
0
def create_channel(data):
    """ Lets a user create a new chat channel in a ws, with a unique name in that ws."""

    chan_name = sanitize_name(data['new_channel'])

    # If name is all whitespace, do nothing:
    if is_whitespace(chan_name):
        return False

    # Check name not already in use in current workspace:
    if chan_name in workspaces[session['curr_ws']]['channels'].keys():
        # This should send back some kind of error message
        return False

    # Otherwise create a new chat channel and send channel list to all users:
    workspaces[session['curr_ws']]['channels'][chan_name] = {
        'messages': {},
        'next_message': 1
    }

    channel_list = list(workspaces[session['curr_ws']]['channels'].keys())

    # Send updated channel list to all users in the workspace:
    emit('channel_list amended', {'channel_list': channel_list},
         room=session['curr_ws'])
Exemplo n.º 2
0
def screen_name():
    """ Update a user's screen name in the database and all chat messages """

    # If user not logged in return to login screen:
    if session.get('user_id') == None:
        return redirect('/login')

    # Get input from form and check screen-name exists:
    new_screen_name = request.form.get("new-screen-name")

    if not new_screen_name or is_whitespace(new_screen_name):
        flash('Please enter your new Screen Name to update it!')
        return redirect('/account')

    # Update screen_name in database and session:
    user_info = User.query.get(session['user_id'])
    user_info.screen_name = new_screen_name
    db.session.commit()
    session['screen_name'] = new_screen_name

    update_profile(session['screen_name'], 'screen_name', workspaces,
                   private_channels)

    flash('Your Screen Name has been changed to: ' + session['screen_name'])
    return redirect('/account')
Exemplo n.º 3
0
def create_workspace(data):
    """ Lets a user create a new workspace, with a unique name. The user then joins the new workspace """

    ws_name = sanitize_name(data['new_workspace'])

    # If name is all whitespace, do nothing:
    if is_whitespace(ws_name):
        return False

    # Check new workspace name not already in use:
    if ws_name in workspaces.keys():
        # This should send back some kind of error message
        return False

    timestamp = datetime.now(pytz.utc).timestamp()
    date = datetime.now().strftime('%d %b %Y')

    # Otherwise create a new workspace:
    workspaces[ws_name] = {
        'channels': {
            'Announcements': {
                'messages': {
                    1: {
                        'message_text':
                        f'Welcome to your new workspace - {ws_name}!',
                        'screen_name': 'Flack-Teams Help',
                        'message_timestamp': timestamp,
                        'message_date': date,
                        'message_id': 1,
                        'profile_img': 'admin.png',
                        'user_id': -1,
                        'edited': False,
                        'edit_text': None,
                        'edit_date': None,
                        'deleted': False,
                        'private': False
                    }
                },
                'next_message': 2
            }
        },
        'users_online': set()
    }

    # Broadcast new workspace creation:
    workspace_list = list(workspaces.keys())
    emit('workspace_list amended', {'workspace_list': workspace_list},
         broadcast=True)

    # Join new workspace in Announcments channel:
    data = {'sign in': False, 'workspace': ws_name}
    join_workspace(data)
Exemplo n.º 4
0
def account():
    """ Show user Account Settings Page, To Change Password, Screen-name or Icon """

    # If user not logged in return to login screen:
    if session.get('user_id') == None:
        return redirect('/login')

    # User reached route via POST (by submitting password change form):
    if request.method == "POST":

        # Get input from form:
        curr_pass = request.form.get("curr-pass")
        new_pass = request.form.get("new-pass")
        confirm = request.form.get("check-pass")

        # Check input fields are correct:
        if not curr_pass or not new_pass or new_pass != confirm or is_whitespace(
                new_pass):
            flash("Please fill in all password fields!")
            return render_template("account.html")

        # Get current password hash to check it matches:
        user_info = User.query.get(session['user_id'])
        logged_pass = user_info.pass_hash

        if not check_password_hash(logged_pass, curr_pass):
            flash("Incorrect current password entered, please try again!")
            return render_template("account.html")

        # Ensure password meets password requirements
        elif not validate_pass(new_pass):
            flash(
                "New password does not meet requirements - must be at least eight chars long including one number and one letter!"
            )
            return render_template("account.html")

        # Otherwise generate new password hash and update the password hash in DBfor this user:
        new_pass_hash = generate_password_hash(new_pass)
        user_info.pass_hash = new_pass_hash
        db.session.commit()

        flash('Password successfully updated!')
        return redirect('/account')

    # User reached route via GET (as by clicking acount link)
    else:
        return render_template('account.html')
Exemplo n.º 5
0
def edit_message(data):
    """ Edit the text of a message in a specific channel. Updates the message for all users """

    print('TRYING TO EDIT MESSAGE')

    timestamp = float(data['timestamp'])
    message_id = int(data['message_id'])
    text = sanitize_message(data['message_text'])
    private = data['private']

    # If message text is all whitespace, do nothing:
    if is_whitespace(text):
        return False

    if not private:
        # Check if message exists in workspaces
        messages = workspaces[session['curr_ws']]['channels'][
            session['curr_chan']]['messages']
        room = session['curr_ws_chan']
    else:
        # Check if message exists in private_channels
        messages = private_channels['channels'][
            session['curr_private']]['messages']
        room = session['curr_private']

    # Check if message exists and user is allowed to edit it:
    if messages.get(message_id) and (messages[message_id]['message_timestamp']
                                     == timestamp) and (
                                         session['user_id']
                                         == messages[message_id]['user_id']):

        messages[message_id]['message_text'] = text
        messages[message_id]['edited'] = True
        messages[message_id]['edit_text'] = 'Message Edited'
        messages[message_id]['edit_date'] = datetime.now().strftime('%d %b %Y')

        emit('emit edited message', {
            'message_id': message_id,
            'timestamp': timestamp,
            'edited_text': messages[message_id]['message_text'],
            'edit_type': messages[message_id]['edit_text'],
            'edit_date': messages[message_id]['edit_date'],
            'deleted': False,
            'private': private
        },
             room=room)
Exemplo n.º 6
0
def send_message(data):
    """ Sends a message to all users in the same room, and stores the message on the server """

    print('Server has received a message, Sending message to users in channel')

    # Get data from incoming message:
    message_text = sanitize_message(data['message'])
    screen_name = session['screen_name']
    workspace = session['curr_ws']
    channel = session['curr_chan']
    ws_channel = session['curr_ws_chan']
    private = session['curr_private']
    profile_img = session['profile_img']

    # If message text is all whitespace, do nothing:
    if is_whitespace(message_text):
        return False

    # Create message object:
    message = {
        'user_id': session['user_id'],
        'message_text': message_text,
        'screen_name': screen_name,
        'message_date': datetime.now().strftime('%d %b %Y'),
        'message_timestamp': datetime.now(pytz.utc).timestamp(),
        'profile_img': profile_img,
        'edited': False,
        'edit_text': None,
        'edit_date': None,
        'deleted': False
    }

    # If public channel message, save to workspaces
    if not data['private']:
        # Save message data to channel log:
        next = workspaces[workspace]['channels'][channel]['next_message']
        message['message_id'] = next
        message['private'] = False
        workspaces[workspace]['channels'][channel]['messages'][next] = message

        # Store up to 100 messages, then overwrite the first message
        workspaces[workspace]['channels'][channel]['next_message'] += 1
        if workspaces[workspace]['channels'][channel]['next_message'] > 100:
            workspaces[workspace]['channels'][channel]['next_message'] = 1

        emit('emit message', {
            'message': message,
            'private': False
        },
             room=ws_channel)
        emit('channel alert', {
            'channel': channel,
            'private': False
        },
             room=workspace)

    # If private channel message, save to private_channels
    else:
        # Save message to private channel log:
        next = private_channels['channels'][private]['next_message']
        message['message_id'] = next
        message['private'] = True
        private_channels['channels'][private]['messages'][next] = message

        # Store up to 100 messages, the overwrite the first message
        private_channels['channels'][private]['next_message'] += 1
        if private_channels['channels'][private]['next_message'] > 100:
            private_channels['channels'][private]['next_message'] = 1

        emit('emit message', {
            'message': message,
            'private': True
        },
             room=private)

        # Get correct room and channel name to emit alert to target user:
        for target_id in session['curr_private']:
            if target_id != session['user_id']:
                channel = private_channels['user_private_list'][target_id][
                    session['curr_private']]['name']
                target_room = f'{(target_id,)}'

                emit('channel alert', {
                    'channel': channel,
                    'private': True
                },
                     room=target_room)
Exemplo n.º 7
0
def register():
    """Register user for the website"""

    # If user is already logged in, return to home screen:
    if session.get('user_id') != None:
        return redirect('/')

    # If reached via POST by submitting form - try to register new user:
    if request.method == 'POST':

        # Get input from registration form:
        username = request.form.get('username')
        screen_name = request.form.get('screenname')
        password = request.form.get('password')
        confirm = request.form.get('confirmation')
        profile_img = request.form.get('profile')
        file = None

        # If form is incomplete, return and flash apology:
        if not all([username, screen_name, password, confirm, profile_img]):
            flash('Please fill in all fields to register!')
            return render_template('register.html')

        # If password and confirmation do not match, return and flash apology:
        elif password != confirm:
            flash('Password and confirmation did not match! Please try again.')
            return render_template('register.html')

        # Ensure password meets password requirements:
        elif not validate_pass(password):
            flash(
                'Password must be eight characters long with at least one number and one letter!'
            )
            return render_template('register.html')

        # If any input is just whitespace chars, ask for new input:
        if is_whitespace(username) or is_whitespace(
                screen_name) or is_whitespace(password):
            flash('Please fill in all fields to register!')
            return render_template('register.html')

        # Check that file is uploaded if own profile img selected:
        if profile_img == 'user_upload':

            result = check_img_upload()

            if not result[0]:
                flash(result[1])
                return render_template('register.html')
            else:
                file = result[1]

        # Otherwise information from registration is complete
        # Check username does not already exist, if it does then ask for a different name:
        user_query = User.query.filter_by(username=username).first()

        if user_query:
            flash(
                'Sorry but that username is already in use, please pick a different username!'
            )
            return render_template('register.html')

        # Otherwise add user to database using hashed password:
        pass_hash = generate_password_hash(password)

        # Add new user to users table:
        new_user = User(username=username,
                        screen_name=screen_name,
                        pass_hash=pass_hash,
                        profile_img=profile_img)
        db.session.add(new_user)
        db.session.commit()

        # Put unique user ID and username into session:
        user_info = User.query.filter_by(username=username).first()
        load_user(user_info, session)

        # If user uploaded a custom image file, add its path to DB, and save in Images folder:
        if file:
            save_user_img(file, app)
            user_info.profile_img = session['profile_img']
            db.session.commit()

        # Go to main chat page
        return redirect('/')

    # If User reaches Route via GET (e.g. clicking registration link):
    else:
        return render_template('register.html')