Exemplo n.º 1
0
def _get_user_require_auth(user_id=None):
    """Return the requested user only if authenticated and authorized.

    Defaults to the current user if no user_id given.

    Guaranteed to return a user object.
    """
    current_user = view_helpers.get_current_user()
    if not current_user:
        raise api_util.ApiBadRequestError('Must authenticate as a user.')

    if not user_id:
        return current_user

    try:
        user_id_bson = bson.ObjectId(user_id)
    except bson.errors.InvalidId:
        raise api_util.ApiBadRequestError(
            'User ID %s is not a valid BSON ObjectId.' % user_id)

    # Does the the current user have permission to get info about this user?
    if (user_id_bson == current_user.id
            or user_id_bson in current_user.friend_ids):
        user = m.User.objects.with_id(user_id_bson)
        if user:
            return user

    raise api_util.ApiForbiddenError(
        'Not authorized to get info about this user.')
Exemplo n.º 2
0
def signup_email():
    """Create a new account using data encoded in the POST body.

    Expects the following form data:
        first_name: E.g. 'Taylor'
        last_name: E.g. 'Swift'
        email: E.g. '*****@*****.**'
        password: E.g. 'iknewyouweretrouble'

    Responds with the session cookie via the `set-cookie` header on success.
    Send the associated cookie for all subsequent API requests that accept
    user authentication.
    """
    # Prevent a CSRF attack from replacing a logged-in user's account with
    # a new account with known credentials
    current_user = view_helpers.get_current_user()
    if current_user:
        return api_util.jsonify({'message': 'A user is already logged in.'})

    params = flask.request.form.copy()

    # Don't log the password
    password = params.pop('password', None)

    rmclogger.log_event(
        rmclogger.LOG_CATEGORY_API,
        rmclogger.LOG_EVENT_SIGNUP,
        {
            'params': params,
            'type': rmclogger.LOGIN_TYPE_STRING_EMAIL,
        },
    )

    first_name = params.get('first_name')
    last_name = params.get('last_name')
    email = params.get('email')

    if not first_name:
        raise api_util.ApiBadRequestError('Must provide first name.')

    if not last_name:
        raise api_util.ApiBadRequestError('Must provide last name.')

    if not email:
        raise api_util.ApiBadRequestError('Must provide email.')

    if not password:
        raise api_util.ApiBadRequestError('Must provide password.')

    try:
        user = m.User.create_new_user_from_email(first_name, last_name, email,
                                                 password)
    except m.User.UserCreationError as e:
        raise api_util.ApiBadRequestError(e.message)

    view_helpers.login_as_user(user)

    return api_util.jsonify(
        {'message': 'Created and logged in user %s' % user.name})
Exemplo n.º 3
0
def add_gcm_course_alert():
    """Adds an alert to notify when a seat opens up in a course/section via
    GCM.

    GCM is used to send push notifications to our Android app.

    Requires the following parameters:
        registration_id: Provided by GCM to identify the device-app pair
        course_id: ID of the course to alert on

    Optional parameters:
        created_date: Timestamp in millis
        expiry_date: Timestamp in millis. Defaults to 1 year later
        term_id: e.g. "2014_01"
        section_type: e.g. "LEC"
        section_num: e.g. "001"
        user_id: ID of the logged in user
    """
    params = flask.request.form

    created_date = datetime.datetime.now()

    expiry_date_param = params.get('expiry_date')
    if expiry_date_param:
        expiry_date = datetime.datetime.fromtimestamp(int(expiry_date_param))
    else:
        expiry_date = created_date + datetime.timedelta(days=365)

    try:
        alert_dict = {
            'registration_id': params['registration_id'],
            'course_id': params['course_id'],
            'created_date': created_date,
            'expiry_date': expiry_date,
            'term_id': params.get('term_id'),
            'section_type': params.get('section_type'),
            'section_num': params.get('section_num'),
            'user_id': params.get('user_id'),
        }
    except KeyError as e:
        raise api_util.ApiBadRequestError('Missing required parameter: %s' %
                                          e.message)

    alert = m.GcmCourseAlert(**alert_dict)

    try:
        alert.save()
    except me.NotUniqueError as e:
        raise api_util.ApiBadRequestError(
            'Alert with the given parameters already exists.')

    return api_util.jsonify({
        'gcm_course_alert': alert.to_dict(),
    })
Exemplo n.º 4
0
def login_email():
    """Attempt to log in a user with the credentials encoded in the POST body.

    Expects the following form data:
        email: E.g. '*****@*****.**'
        password: E.g. 'iknewyouweretrouble'

    Responds with the session cookie via the `set-cookie` header on success.
    Send the associated cookie for all subsequent API requests that accept
    user authentication.
    """
    # Prevent a CSRF attack from replacing a logged-in user's account with the
    # attacker's.
    current_user = view_helpers.get_current_user()
    if current_user:
        return api_util.jsonify({'message': 'A user is already logged in.'})

    params = flask.request.form.copy()

    # Don't log the password
    password = params.pop('password', None)

    rmclogger.log_event(
        rmclogger.LOG_CATEGORY_API,
        rmclogger.LOG_EVENT_LOGIN,
        {
            'params': params,
            'type': rmclogger.LOGIN_TYPE_STRING_EMAIL,
        },
    )

    email = params.get('email')

    if not email:
        raise api_util.ApiBadRequestError('Must provide email.')

    if not password:
        raise api_util.ApiBadRequestError('Must provide password.')

    user = m.User.auth_user(email, password)

    if not user:
        raise api_util.ApiNotFoundError('Incorrect email or password.')

    view_helpers.login_as_user(user)

    return api_util.jsonify({'message': 'Logged in user %s' % user.name})
Exemplo n.º 5
0
def add_course_to_shortlist(course_id):
    """Adds the given course to the user's shortlist.

    Idempotent.
    """
    user = _get_user_require_auth()
    user_course = user.add_course(course_id, m.Term.SHORTLIST_TERM_ID)

    if user_course is None:
        raise api_util.ApiBadRequestError(
            'Could not add course %s to shortlist. :(' % course_id)

    return api_util.jsonify({
        'user_course': user_course.to_dict(),
    })
Exemplo n.º 6
0
def get_access_token_info(access_token):
    """Returns info about the given Facebook access token.

    Verifies that the access token was issued for Flow. This prevents an
    attacker from hijacking a user's Flow account by providing a valid access
    token issued for another FB app.

    For return data, see (https://developers.facebook.com/docs/facebook-login
            /manually-build-a-login-flow/#confirm)
    """
    res = requests.get('https://graph.facebook.com/debug_token'
            '?input_token=%s&access_token=%s|%s' % (
                access_token,
                app.config['FB_APP_ID'],
                app.config['FB_APP_SECRET']))

    if not res.ok or not res.json.get('data'):
        logging.error('Failed verifying FB access token. FB response: %s' %
                res.json)
        raise api_util.ApiBadRequestError('Failed verifying FB access token.')

    return res.json['data']