Beispiel #1
0
    def wrapper(*args, **kwargs):
        user_data = models.UserData.current()

        if user_data and (users.is_current_user_admin() or user_data.developer):
            return func(*args, **kwargs)

        return unauthorized_response()
Beispiel #2
0
def _attempt_problem_wrong(exercise_name):
    user_data = models.UserData.current()

    if user_data and exercise_name:
        user_exercise = user_data.get_or_insert_exercise(models.Exercise.get_by_name(exercise_name))
        return make_wrong_attempt(user_data, user_exercise)

    return unauthorized_response()
Beispiel #3
0
def reset_problem_streak(exercise_name):
    user_data = models.UserData.current()

    if user_data and exercise_name:
        user_exercise = user_data.get_or_insert_exercise(models.Exercise.get_by_name(exercise_name))
        return reset_streak(user_data, user_exercise)

    return unauthorized_response()
Beispiel #4
0
def reset_problem_streak(exercise_name):
    user_data = models.UserData.current()

    if user_data and exercise_name:
        user_exercise = user_data.get_or_insert_exercise(
            models.Exercise.get_by_name(exercise_name))
        return reset_streak(user_data, user_exercise)

    return unauthorized_response()
Beispiel #5
0
    def wrapper(*args, **kwargs):

        # Make sure current UserData exists as well as is_current_user_admin
        # because UserData properly verifies xsrf token
        user_data = models.UserData.current()

        if user_data and users.is_current_user_admin():
            return func(*args, **kwargs)

        return unauthorized_response()
Beispiel #6
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph = attempt_problem(
                user_data,
                user_exercise,
                problem_number,
                request.request_int("attempt_number"),
                request.request_string("attempt_content"),
                request.request_string("sha1"),
                request.request_string("seed"),
                request.request_bool("complete"),
                request.request_int("count_hints", default=0),
                int(request.request_float("time_taken")),
                request.request_string("non_summative"),
                request.request_string("problem_type"),
                request.remote_addr,
            )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if (user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if (user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (
                    user_data.points == points_earned) else points_earned

            add_action_results(
                user_exercise, {
                    "exercise_message_html":
                    templatetags.exercise_message(
                        exercise, user_data.coaches,
                        user_exercise_graph.states(exercise.name)),
                    "points_earned": {
                        "points": points_earned
                    },
                    "attempt_correct":
                    request.request_bool("complete")
                })

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present",
                    problem_number)
    return unauthorized_response()
def login_required_and(admin_required=False,
                       developer_required=False,
                       moderator_required=False,
                       child_user_allowed=True,
                       demo_user_allowed=False,
                       phantom_user_allowed=True):
    """Decorator for validating an authenticated request.

    Checking oauth/cookie is the way to tell whether an API client is
    'logged in', since they can only have gotten an oauth token (or
    cookie token) via the login process.

    In addition to checking whether the user is logged in, this
    function also checks access based on the *type* of the user: if
    demo_user_allowed==False, for instance, and the logged-in user is
    a demo user, then access will be denied.

    (Exception: if the user is an admin user, then access is *always*
    allowed, and the only check we make is if they're logged in.)

    The default values specify the default permissions: for instance,
    phantom users are considered a valid user by this routine, and
    under-13 users are allowed access all urls unless explicitly
    stated otherwise.

    (Exception: under-13 users are always disallowed for oauth requests
    unless the oauth consumer is preapproved/anointed by us. No third party
    apps can access under-13 account data.)

    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                verify_and_cache_oauth_or_cookie(request)
            except OAuthError, e:
                return oauth_error_response(e)
            except NotLoggedInError, e:
                # TODO(csilvers): just count how often this happens intead
                # of logging.  Why warn about something we can't control?
                # The only reason is it's possible this is caused by a bug.
                logging.warning('No login info found via %s\nCookie: %s'
                                % (e, os.environ.get('HTTP_COOKIE', '')))
                return unauthorized_response()

            try:
                user_util.verify_login(admin_required, developer_required,
                                       moderator_required, child_user_allowed,
                                       demo_user_allowed, phantom_user_allowed)
            except user_util.LoginFailedError:
                return unauthorized_response()

            return func(*args, **kwargs)
Beispiel #8
0
def hint_problem_number(exercise_name, problem_number):

    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            prev_user_exercise_graph = models.UserExerciseGraph.get(user_data)

            attempt_number = request.request_int("attempt_number")
            count_hints = request.request_int("count_hints")

            user_exercise, user_exercise_graph, goals_updated = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    attempt_number,
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    count_hints,
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            user_states = user_exercise_graph.states(exercise.name)
            review_mode = request.request_bool("review_mode", default=False)
            exercise_message_html = templatetags.exercise_message(exercise,
                    user_exercise_graph, review_mode=review_mode)

            add_action_results(user_exercise, {
                "exercise_message_html": exercise_message_html,
                "exercise_state": {
                    "state": [state for state in user_states if user_states[state]],
                    "template" : exercise_message_html,
                }
            })

            # A hint will count against the user iff they haven't attempted the question yet and it's their first hint
            if attempt_number == 0 and count_hints == 1:
                bingo("hints_costly_hint")
                bingo("hints_costly_hint_binary")

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()
 def decorator(func):
     @wraps(func)
     def wrapper(*args, **kwargs):
         try:
             verify_and_cache_oauth_or_cookie(request)
         except OAuthError, e:
             return oauth_error_response(e)
         except NotLoggedInError, e:
             # TODO(csilvers): just count how often this happens intead
             # of logging.  Why warn about something we can't control?
             # The only reason is it's possible this is caused by a bug.
             logging.warning('No login info found via %s\nCookie: %s'
                             % (e, os.environ.get('HTTP_COOKIE', '')))
             return unauthorized_response()
Beispiel #10
0
 def decorator(func):
     @wraps(func)
     def wrapper(*args, **kwargs):
         try:
             verify_and_cache_oauth_or_cookie(request)
         except OAuthError, e:
             return oauth_error_response(e)
         except NotLoggedInError, e:
             # TODO(csilvers): just count how often this happens intead
             # of logging.  Why warn about something we can't control?
             # The only reason is it's possible this is caused by a bug.
             logging.warning('No login info found via %s\nCookie: %s'
                             % (e, os.environ.get('HTTP_COOKIE', '')))
             return unauthorized_response()
Beispiel #11
0
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                verify_and_cache_oauth_or_cookie(request)
            except OAuthError, e:
                return oauth_error_response(e)

            try:
                user_util.verify_login(admin_required, developer_required,
                                       moderator_required, child_user_allowed,
                                       demo_user_allowed, phantom_user_allowed)
            except user_util.LoginFailedError:
                return unauthorized_response()

            return func(*args, **kwargs)
Beispiel #12
0
 def wrapper(*args, **kwargs):
     # This checks flask.g.is_anointed, though only if the
     # request was an oauth request (and not a cookie request).
     if is_valid_request(request):   # only check if we're an oauth req.
         try:
             verify_and_cache_oauth_or_cookie(request)
             if not getattr(flask.g, "is_anointed", False):
                 raise OAuthError("Consumer access denied.")
         except OAuthError, e:
             return oauth_error_response(e)
         except NotLoggedInError, e:
             # TODO(csilvers): just count how often this happens intead
             # of logging.  Why warn about something we can't control?
             # The only reason is it's possible this is caused by a bug.
             logging.warning('is_anointed: no login info found via %s' % e)
             return unauthorized_response()
 def wrapper(*args, **kwargs):
     # This checks flask.g.is_anointed, though only if the
     # request was an oauth request (and not a cookie request).
     if is_valid_request(request):   # only check if we're an oauth req.
         try:
             verify_and_cache_oauth_or_cookie(request)
             if not getattr(flask.g, "is_anointed", False):
                 raise OAuthError("Consumer access denied.")
         except OAuthError, e:
             return oauth_error_response(e)
         except NotLoggedInError, e:
             # TODO(csilvers): just count how often this happens intead
             # of logging.  Why warn about something we can't control?
             # The only reason is it's possible this is caused by a bug.
             logging.warning('is_anointed: no login info found via %s' % e)
             return unauthorized_response()
Beispiel #14
0
def hint_problem_number(exercise_name, problem_number):

    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            attempt_number = request.request_int("attempt_number")
            count_hints = request.request_int("count_hints")

            user_exercise, user_exercise_graph = attempt_problem(
                user_data,
                user_exercise,
                problem_number,
                attempt_number,
                request.request_string("attempt_content"),
                request.request_string("sha1"),
                request.request_string("seed"),
                request.request_bool("complete"),
                count_hints,
                int(request.request_float("time_taken")),
                request.request_string("non_summative"),
                request.request_string("problem_type"),
                request.remote_addr,
            )

            add_action_results(
                user_exercise, {
                    "exercise_message_html":
                    templatetags.exercise_message(
                        exercise, user_data.coaches,
                        user_exercise_graph.states(exercise.name)),
                })

            # A hint will count against the user iff they haven't attempted the question yet and it's their first hint
            if attempt_number == 0 and count_hints == 1:
                bingo("hints_costly_hint")
                bingo("hints_costly_hint_binary")

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present",
                    problem_number)
    return unauthorized_response()
Beispiel #15
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    request.request_int("attempt_number"),
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    request.request_int("count_hints", default=0),
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if(user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if(user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (user_data.points == points_earned) else points_earned

            add_action_results(user_exercise, {
                "exercise_message_html": templatetags.exercise_message(exercise, user_data.coaches, user_exercise_graph.states(exercise.name)),
                "points_earned" : { "points" : points_earned },
                "attempt_correct" : request.request_bool("complete")
            })

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()
Beispiel #16
0
def log_user_video(youtube_id):
    if (not request.request_string("seconds_watched") or
        not request.request_string("last_second_watched")):
        logging.critical("Video log request with no parameters received.")
        return api_invalid_param_response("Must supply seconds_watched and" +
            "last_second_watched")

    user_data = models.UserData.current()
    if not user_data:
        logging.warning("Video watched with no user_data present")
        return unauthorized_response()

    video_key_str = request.request_string("video_key")

    if not youtube_id and not video_key_str:
        return api_invalid_param_response("Must supply youtube_id or video_key")

    video_log = None
    if video_key_str:
        key = db.Key(video_key_str)
        video = db.get(key)
    else:
        video = models.Video.all().filter("youtube_id =", youtube_id).get()

    if not video:
        return api_error_response("Could not find video")

    seconds_watched = int(request.request_float("seconds_watched", default=0))
    last_second = int(request.request_float("last_second_watched", default=0))

    user_video, video_log, _, goals_updated = models.VideoLog.add_entry(
        user_data, video, seconds_watched, last_second)

    if video_log:
        action_results = {}
        action_results['user_video'] = user_video
        if goals_updated:
            action_results['updateGoals'] = [g.get_visible_data(None)
                for g in goals_updated]

        add_action_results(video_log, action_results)

    return video_log
Beispiel #17
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph, goals_updated = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    request.request_int("attempt_number"),
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    request.request_int("count_hints", default=0),
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if(user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if(user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (user_data.points == points_earned) else points_earned

            user_states = user_exercise_graph.states(exercise.name)
            correct = request.request_bool("complete")
            review_mode = request.request_bool("review_mode", default=False)

            action_results = {
                "exercise_state": {
                    "state": [state for state in user_states if user_states[state]],
                    "template" : templatetags.exercise_message(exercise,
                        user_exercise_graph, review_mode=review_mode),
                },
                "points_earned": {"points": points_earned},
                "attempt_correct": correct,
            }

            if goals_updated:
                action_results['updateGoals'] = [g.get_visible_data(None) for g in goals_updated]

            if review_mode:
                action_results['reviews_left'] = (
                    user_exercise_graph.reviews_left_count() + (1 - correct))

            add_action_results(user_exercise, action_results)
            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()