Esempio n. 1
0
def verify_email(username, code):
    """
    Verifies to the system that an email address exists, and assigns it to a user.
    Expected to be used only by users clicking links in email-verfication emails.
    Not part of the documented API.
    """

    change_request = PendingEmail(username)

    if not change_request.in_db:
        return "No such change request", 404, PLAINTEXT_HEADER

    email_change_days = config.config.getint('nemesis', 'email_change_days')
    max_age = timedelta(days=email_change_days)

    if change_request.age > max_age:
        return "Request not valid", 410, PLAINTEXT_HEADER

    if change_request.verify_code != code:
        return "Invalid verification code", 403, PLAINTEXT_HEADER

    log_action('changing email',
               user=username,
               new_email=change_request.new_email)

    u = User(change_request.username)
    u.set_email(change_request.new_email)
    u.save()

    return "Email address successfully changed", 200, PLAINTEXT_HEADER
Esempio n. 2
0
def verify_email(username, code):
    """
    Verifies to the system that an email address exists, and assigns it to a user.
    Expected to be used only by users clicking links in email-verfication emails.
    Not part of the documented API.
    """

    change_request = PendingEmail(username)

    if not change_request.in_db:
        return "No such change request", 404

    if change_request.age > timedelta(days = 2):
        return "Request not valid", 410

    if change_request.verify_code != code:
        return "Invalid verification code", 403

    log_action('changing email', user = username, new_email = change_request.new_email)

    u = User(change_request.username)
    u.set_email(change_request.new_email)
    u.save()

    return "Email address successfully changed", 200
Esempio n. 3
0
def verify_email(username, code):
    """
    Verifies to the system that an email address exists, and assigns it to a user.
    Expected to be used only by users clicking links in email-verfication emails.
    Not part of the documented API.
    """

    change_request = PendingEmail(username)

    if not change_request.in_db:
        return "No such change request", 404

    if change_request.age > timedelta(days=2):
        return "Request not valid", 410

    if change_request.verify_code != code:
        return "Invalid verification code", 403

    log_action('changing email',
               user=username,
               new_email=change_request.new_email)

    u = User(change_request.username)
    u.set_email(change_request.new_email)
    u.save()

    return "Email address successfully changed", 200
Esempio n. 4
0
def verify_email(username, code):
    """
    Verifies to the system that an email address exists, and assigns it to a user.
    Expected to be used only by users clicking links in email-verfication emails.
    Not part of the documented API.
    """

    change_request = PendingEmail(username)

    if not change_request.in_db:
        return "No such change request", 404, PLAINTEXT_HEADER

    email_change_days = config.config.getint('nemesis', 'email_change_days')
    max_age = timedelta(days = email_change_days)

    if change_request.age > max_age:
        return "Request not valid", 410, PLAINTEXT_HEADER

    if change_request.verify_code != code:
        return "Invalid verification code", 403, PLAINTEXT_HEADER

    log_action('changing email', user = username, new_email = change_request.new_email)

    u = User(change_request.username)
    u.set_email(change_request.new_email)
    u.save()

    return "Email address successfully changed", 200, PLAINTEXT_HEADER
Esempio n. 5
0
def send_password_reset(requesting_user, userid):
    user_to_update = User.create_user(userid)
    if not requesting_user.can_administrate(user_to_update):
        return AUTHORIZATION_DENIED

    verify_code = helpers.create_verify_code(user_to_update.username,
                                             requesting_user.username)

    ppr = PendingPasswordReset(user_to_update.username)
    ppr.requestor_username = requesting_user.username
    ppr.verify_code = verify_code
    ppr.save()

    log_action('sending password reset', ppr)

    url = url_for('reset_password',
                  username=user_to_update.username,
                  code=verify_code,
                  _external=True)
    ppr.send_reset_email(
        user_to_update.email,
        user_to_update.first_name,
        url,
        "{0} {1}".format(requesting_user.first_name,
                         requesting_user.last_name),
    )

    return "{}", 202
Esempio n. 6
0
def activate_account(username, code):
    """
    Verifies to the system that an email address exists, and that the related
    account should be made into a full account.
    Expected to be used only by users clicking links in account-activation emails.
    Not part of the documented API.
    """

    pu = PendingUser(username)

    if not pu.in_db:
        return "No such user account", 404

    if pu.age > timedelta(days=2):
        return "Request not valid", 410

    if pu.verify_code != code:
        return "Invalid verification code", 403

    log_action('activating user', pu)

    from libnemesis import srusers
    new_pass = srusers.users.GenPasswd()

    u = User(username)
    u.set_email(pu.email)
    u.set_team(pu.team)
    u.set_college(pu.college)
    u.set_password(new_pass)
    u.make_student()
    u.save()

    # let the team-leader know
    rq_user = User.create_user(pu.teacher_username)
    email_vars = {
        'name': rq_user.first_name,
        'au_username': username,
        'au_first_name': u.first_name,
        'au_last_name': u.last_name
    }
    mailer.email_template(rq_user.email, 'user_activated_team_leader',
                          email_vars)

    pu.delete()

    html = open(PATH + "/templates/activate.html").read()
    replacements = {
        'first_name': u.first_name,
        'last_name': u.last_name,
        'password': new_pass,
        'email': u.email,
        'username': username,
        'root': url_for('.index')
    }

    html = html.format(**replacements)

    return html, 200
Esempio n. 7
0
    def test_log_action_objects(self):
        class Foo(object):
            def __repr__(self):
                return 'Foo(bacon)'

        helpers.log_action('action-my', Foo())
        logged = self._stream.getvalue()
        expected = "action-my: Foo(bacon)"
        assert expected in logged
Esempio n. 8
0
    def test_log_action_objects(self):
        class Foo(object):
            def __repr__(self):
                return 'Foo(bacon)'

        helpers.log_action('action-my', Foo())
        logged = self._stream.getvalue()
        expected = "action-my: Foo(bacon)"
        assert expected in logged
Esempio n. 9
0
 def test_log_action(self):
     helpers.log_action('my-action', 'foo', bar='jam', spam='ham')
     logged = self._stream.getvalue()
     expected = (
         # Cope with variable dictionary ordering
         "my-action: foo, bar: jam, spam: ham\n",
         "my-action: foo, spam: ham, bar: jam\n",
     )
     assert logged in expected
Esempio n. 10
0
def register_user(requesting_user):
    if not requesting_user.can_register_users:
        return json.dumps({"error":"YOU_CANT_REGISTER_USERS"}), 403

    teacher_username = requesting_user.username
    college_group    = request.form["college"].strip()
    first_name       = request.form["first_name"].strip()
    last_name        = request.form["last_name"].strip()
    email            = request.form["email"].strip()
    team             = request.form["team"].strip()

    if College(college_group) not in requesting_user.colleges:
        return json.dumps({"error":"BAD_COLLEGE"}), 403

    if team not in [t.name for t in College(college_group).teams]:
        return json.dumps({"error":"BAD_TEAM"}), 403

    if not helpers.is_email_valid(email):
        return json.dumps({"error":"BAD_EMAIL"}), 403

    if not helpers.is_name_valid(first_name):
        return json.dumps({"error":"BAD_FIRST_NAME"}), 403

    if not helpers.is_name_valid(last_name):
        return json.dumps({"error":"BAD_LAST_NAME"}), 403

    if User.name_used(first_name, last_name) or helpers.email_used(email):
        return json.dumps({"error":"DETAILS_ALREADY_USED"}), 403

    u = User.create_new_user(requesting_user, college_group, first_name, last_name)
    verify_code = helpers.create_verify_code(u.username, email)

    pu = PendingUser(u.username)
    pu.teacher_username = teacher_username
    pu.college = college_group
    pu.email = email
    pu.team = team
    pu.verify_code = verify_code
    pu.save()

    log_action('registering user', pu)

    url = url_for('activate_account', username=u.username, code=verify_code, _external=True)
    pu.send_welcome_email(first_name, url)

    rqu_email_vars = { 'name': requesting_user.first_name,
            'activation_days': ACTIVATION_DAYS,
              'pu_first_name': first_name,
               'pu_last_name': last_name,
                'pu_username': pu.username,
                 'pu_college': College(pu.college).name,
                   'pu_email': pu.email,
                    'pu_team': pu.team
                      }
    mailer.email_template(requesting_user.email, 'user_requested', rqu_email_vars)

    return "{}", 202
Esempio n. 11
0
def activate_account(username, code):
    """
    Verifies to the system that an email address exists, and that the related
    account should be made into a full account.
    Expected to be used only by users clicking links in account-activation emails.
    Not part of the documented API.
    """

    pu = PendingUser(username)

    if not pu.in_db:
        return "No such user account", 404

    if pu.age > timedelta(days = 2):
        return "Request not valid", 410

    if pu.verify_code != code:
        return "Invalid verification code", 403

    log_action('activating user', pu)

    from libnemesis import srusers
    new_pass = srusers.users.GenPasswd()

    u = User(username)
    u.set_email(pu.email)
    u.set_team(pu.team)
    u.set_college(pu.college)
    u.set_password(new_pass)
    u.make_student()
    u.save()

    # let the team-leader know
    rq_user = User.create_user(pu.teacher_username)
    email_vars = { 'name': rq_user.first_name,
            'au_username': username,
          'au_first_name': u.first_name,
           'au_last_name': u.last_name
                 }
    mailer.email_template(rq_user.email, 'user_activated_team_leader', email_vars)

    pu.delete()

    html = open(PATH + "/templates/activate.html").read()
    replacements = { 'first_name': u.first_name
                   ,  'last_name': u.last_name
                   ,   'password': new_pass
                   ,      'email': u.email
                   ,   'username': username
                   ,       'root': url_for('.index')
                   }

    html = html.format(**replacements)

    return html, 200
Esempio n. 12
0
def reset_password(username, code):
    """
    Resets a user's password after they've clicked a link in an email we
    sent them, then serves up a page for them to change their password.
    Not part of the documented API.
    """

    ppr = PendingPasswordReset(username)

    if not ppr.in_db:
        return "No such user account", 404, PLAINTEXT_HEADER

    if ppr.age > timedelta(days=PASSWORD_RESET_DAYS):
        return "Request not valid", 410, PLAINTEXT_HEADER

    if ppr.verify_code != code:
        return "Invalid verification code", 403, PLAINTEXT_HEADER

    log_action('resetting user password', ppr)

    from libnemesis import srusers
    new_pass = srusers.users.GenPasswd()

    u = User(username)
    u.set_password(new_pass)
    # No need to save since set_password happens immediately

    ppr.delete()

    html = open(PATH + "/templates/password_reset.html").read()
    replacements = {
        'first_name': u.first_name,
        'last_name': u.last_name,
        'password': new_pass,
        'username': username,
        'root': url_for('.index')
    }

    html = html.format(**replacements)

    return html, 200, CSP_HEADER
Esempio n. 13
0
def ajax_verify():

    if not 'password' in request.form or not 'type' in request.form:
        return "password or type field missing", 200

    uid = request.form.get('uid')
    password = request.form.get('password')
    opentype = request.form.get('type')

    if helpers.verify_password(uid, password):

        helpers.log_action(opentype, uid)

        if opentype == 'Open':
            door_operator.open_door()
        elif opentype == 'Close':
            door_operator.close_door()

        return jsonify(response=True)

    return jsonify(response=False)
Esempio n. 14
0
def ajax_verify():

    if not 'password' in request.form or not 'type' in request.form:
        return "password or type field missing", 200

    uid = request.form.get('uid')
    password = request.form.get('password')
    opentype = request.form.get('type')

    if helpers.verify_password(uid, password):

        helpers.log_action(opentype, uid)

        if opentype == 'Open':
            door_operator.open_door()
        elif opentype == 'Close':
            door_operator.close_door()

        return jsonify(response=True)

    return jsonify(response=False)
Esempio n. 15
0
def reset_password(username, code):
    """
    Resets a user's password after they've clicked a link in an email we
    sent them, then serves up a page for them to change their password.
    Not part of the documented API.
    """

    ppr = PendingPasswordReset(username)

    if not ppr.in_db:
        return "No such user account", 404, PLAINTEXT_HEADER

    if ppr.age > timedelta(days = PASSWORD_RESET_DAYS):
        return "Request not valid", 410, PLAINTEXT_HEADER

    if ppr.verify_code != code:
        return "Invalid verification code", 403, PLAINTEXT_HEADER

    log_action('resetting user password', ppr)

    from libnemesis import srusers
    new_pass = srusers.users.GenPasswd()

    u = User(username)
    u.set_password(new_pass)
    # No need to save since set_password happens immediately

    ppr.delete()

    html = open(PATH + "/templates/password_reset.html").read()
    replacements = { 'first_name': u.first_name
                   ,  'last_name': u.last_name
                   ,   'password': new_pass
                   ,   'username': username
                   ,       'root': url_for('.index')
                   }

    html = html.format(**replacements)

    return html, 200, CSP_HEADER
Esempio n. 16
0
def send_password_reset(requesting_user, userid):
    user_to_update = User.create_user(userid)
    if not requesting_user.can_administrate(user_to_update):
        return AUTHORIZATION_DENIED

    verify_code = helpers.create_verify_code(user_to_update.username, requesting_user.username)

    ppr = PendingPasswordReset(user_to_update.username)
    ppr.requestor_username = requesting_user.username
    ppr.verify_code = verify_code
    ppr.save()

    log_action('sending password reset', ppr)

    url = url_for('reset_password', username=user_to_update.username, code=verify_code, _external=True)
    ppr.send_reset_email(
        user_to_update.email,
        user_to_update.first_name,
        url,
        "{0} {1}".format(requesting_user.first_name, requesting_user.last_name),
    )

    return "{}", 202
Esempio n. 17
0
 def test_log_action(self):
     helpers.log_action('my-action', 'foo', bar = 'jam', spam = 'ham')
     logged = self._stream.getvalue()
     expected = "my-action: foo, bar: jam, spam: ham"
     assert expected in logged
Esempio n. 18
0
 def test_log_action(self):
     helpers.log_action('my-action', 'foo', bar='jam', spam='ham')
     logged = self._stream.getvalue()
     expected = "my-action: foo, bar: jam, spam: ham"
     assert expected in logged
Esempio n. 19
0
def register_user():
    ah = AuthHelper(request)

    if not ah.auth_will_succeed:
        return ah.auth_error_json, 403

    requesting_user = ah.user
    if not requesting_user.can_register_users:
        return json.dumps({"error": "YOU_CANT_REGISTER_USERS"}), 403

    teacher_username = requesting_user.username
    college_group = request.form["college"].strip()
    first_name = request.form["first_name"].strip()
    last_name = request.form["last_name"].strip()
    email = request.form["email"].strip()
    team = request.form["team"].strip()

    if College(college_group) not in requesting_user.colleges:
        return json.dumps({"error": "BAD_COLLEGE"}), 403

    if team not in [t.name for t in College(college_group).teams]:
        return json.dumps({"error": "BAD_TEAM"}), 403

    if not helpers.is_email_valid(email):
        return json.dumps({"error": "BAD_EMAIL"}), 403

    if not helpers.is_name_valid(first_name):
        return json.dumps({"error": "BAD_FIRST_NAME"}), 403

    if not helpers.is_name_valid(last_name):
        return json.dumps({"error": "BAD_LAST_NAME"}), 403

    if User.name_used(first_name, last_name) or helpers.email_used(email):
        return json.dumps({"error": "DETAILS_ALREADY_USED"}), 403

    u = User.create_new_user(requesting_user, college_group, first_name,
                             last_name)
    verify_code = helpers.create_verify_code(u.username, email)

    pu = PendingUser(u.username)
    pu.teacher_username = teacher_username
    pu.college = college_group
    pu.email = email
    pu.team = team
    pu.verify_code = verify_code
    pu.save()

    log_action('registering user', pu)

    url = url_for('activate_account',
                  username=u.username,
                  code=verify_code,
                  _external=True)
    pu.send_welcome_email(first_name, url)

    rqu_email_vars = {
        'name': requesting_user.first_name,
        'pu_first_name': first_name,
        'pu_last_name': last_name,
        'pu_username': pu.username,
        'pu_college': College(pu.college).name,
        'pu_email': pu.email,
        'pu_team': pu.team
    }
    mailer.email_template(requesting_user.email, 'user_requested',
                          rqu_email_vars)

    return "{}", 202