def use_promotion_code(course_id): course_id = course_id.lower() ucs = m.UserCourse.objects(course_id=course_id, user_id=current_identity.id).first() promotion = util.json_loads(flask.request.data) promotion_code = m.PromotionCode.objects(code=promotion['code']).first() if not ucs: ucs = m.UserCourse(course_id=course_id, user_id=current_identity.id) ucs.save() if not promotion_code or promotion_code.quantity <= 0: flask.abort(403) promotion_code.quantity = promotion_code.quantity - 1 if promotion_code._type == 'halfmonthfree': ucs.payment_success = True ucs.read = True ucs.payment_at = datetime.utcnow() ucs.start_from = datetime.utcnow() ucs.expired_at = datetime.utcnow() + timedelta(days=15) ucs.promotion_code = promotion_code['code'] ucs.save() promotion_code.save() return util.json_dumps(ucs.to_mongo())
def update_prof_comment(prof_id): course_prof_comment = m.CourseProfessorComment.objects(id=prof_id).first() comment = util.json_loads(flask.request.data) current_user = view_helpers.get_current_user() if not current_user or comment[ 'user_id'] != current_user.id or course_prof_comment is None: return flask.abort(400) if 'course_id' not in comment or 'professor_id' not in comment: return flask.abort(400) course_prof_comment.update_by_dict(comment) course_prof_comment.save() return util.json_dumps({})
def code_for_token(code, config, cmd_line_debug=False): """Returns a dictionary containing the user's Facebook access token and seconds until it expires from now See https://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens/ Right now, the resulting token is a short-lived token (~2 hours). But it's possible that this is wrong and that it should be a long-term token instead. See https://developers.facebook.com/bugs/341793929223330/ Args: code: The code we get from their fb_signed_request Returns { 'access_token': 'token-here-blarg', 'expires': 6200, } """ # Since we're exchanging a client-side token, redirect_uri should be '' params = { 'client_id': rmc_settings.fb_app_id, 'redirect_uri': '', 'client_secret': rmc_settings.fb_app_secret, 'code': code, } resp = requests.get('https://graph.facebook.com/oauth/access_token', params=params) if resp.status_code != 200: err = util.json_loads(resp.text) if (err.get('error').get('message') == USED_AUTH_CODE_MSG and err.get('error').get('code') == 100): logging.info('code_for_token failed (%d) with text:\n%s' % (resp.status_code, resp.text)) else: logging.warn('code_for_token failed (%d) with text:\n%s' % (resp.status_code, resp.text)) result = dict(urlparse.parse_qsl(resp.text)) if cmd_line_debug: print "result dict:" print result return resp return result
def create_prof_comment(): comment = util.json_loads(flask.request.data) current_user = view_helpers.get_current_user() if not current_user or comment['user_id'] != current_user.id: return flask.abort(400) if 'course_id' not in comment or 'professor_id' not in comment: return flask.abort(400) comment_obj = m.CourseProfessorComment( course_id=comment['course_id'], professor_id=comment['professor_id'], user_id=comment['user_id']) comment_obj.update_by_dict(comment) comment_obj.save() saved_comment_obj = comment_obj.to_mongo() if '_id' in saved_comment_obj: saved_comment_obj['id'] = str(saved_comment_obj['_id']) return util.json_dumps(saved_comment_obj)
def get_friend_list(token): ''' Return a list of fbids for the Facebook user associated with token ''' params = { 'access_token': token, } resp = requests.get('https://graph.facebook.com/me/friends', params=params) resp_dict = util.json_loads(resp.text) if 'error' in resp_dict: if resp_dict.get('error').get('type') == 'OAuthException': raise FacebookOAuthException() raise Exception(resp.text) fbid_list = [] if 'data' in resp_dict: for entry in resp_dict['data']: fbid_list.append(entry['id']) else: raise Exception('"data" not in dict (%s)' % resp_dict) return fbid_list
def parse_signed_request(signed_request, secret): """ Returns a dict of the the Facebook signed request object See https://developers.facebook.com/docs/authentication/signed_request/ """ l = signed_request.split('.', 2) encoded_sig = l[0] payload = l[1] sig = base64_url_decode(encoded_sig) data = util.json_loads(base64_url_decode(payload)) if data.get('algorithm').upper() != 'HMAC-SHA256': logging.error('Unknown algorithm during signed request decode') return None expected_sig = (hmac.new(secret, msg=payload, digestmod=hashlib.sha256).digest()) if sig != expected_sig: return None return data
def save(): comment = util.json_loads(flask.request.data) current_user_id = current_identity.id print comment, current_user_id if 'course_id' not in comment or 'course_id' not in comment: return flask.abort(400) if str(comment['user_id']) != current_user_id: return flask.abort(400) comment_obj = None if 'id' in comment: comment_obj = m.CourseComment.objects(id=comment['id']).first() if comment_obj is None: comment_obj = m.CourseComment(course_id=comment['course_id'], user_id=comment['user_id']) comment_obj.update_by_dict(comment) comment_obj.save() saved_comment_obj = comment_obj.to_mongo() if '_id' in saved_comment_obj: saved_comment_obj['id'] = str(saved_comment_obj['_id']) return util.json_dumps(saved_comment_obj)
def user_course(): uc_data = util.json_loads(flask.request.data) user = view_helpers.get_current_user() rmclogger.log_event( rmclogger.LOG_CATEGORY_API, rmclogger.LOG_EVENT_USER_COURSE, { 'uc_data': uc_data, 'user_id': user.id, }, ) # Validate request object course_id = uc_data.get('course_id') term_id = uc_data.get('term_id') if course_id is None or term_id is None: logging.error("/api/user/course got course_id (%s) and term_id (%s)" % (course_id, term_id)) # TODO(david): Perhaps we should have a request error function that # returns a 400 raise exceptions.ImATeapot('No course_id or term_id set') # if not m.UserCourse.can_review(term_id): # logging.warning("%s attempted to rate %s in future/shortlist term %s" # % (user.id, course_id, term_id)) # raise exceptions.ImATeapot( # "Can't review a course in the future or shortlist") # Fetch existing UserCourse uc = m.UserCourse.objects( user_id=user.id, course_id=uc_data['course_id'], term_id=uc_data['term_id'] ).first() if uc is None: logging.error("/api/user/course User course not found for " "user_id=%s course_id=%s term_id=%s" % (user.id, course_id, term_id)) # TODO(david): Perhaps we should have a request error function that # returns a 400 raise exceptions.ImATeapot('No user course found') orig_points = uc.num_points # TODO(Sandy): Consider the case where the user picked a professor and # rates them, but then changes the professor. We need to remove the ratings # from the old prof's aggregated ratings and add them to the new prof's # Maybe create professor if newly added if uc_data.get('new_prof_added'): new_prof_name = uc_data['new_prof_added'] # TODO(mack): should do guess_names first, and use that to # generate the id prof_id = m.Professor.get_id_from_name(new_prof_name) uc.professor_id = prof_id # TODO(Sandy): Have some kind of sanity check for professor names. # Don't allow ridiculousness like "Santa Claus", "aksnlf", # "swear words" if m.Professor.objects(id=prof_id).count() == 0: first_name, last_name = m.Professor.guess_names(new_prof_name) m.Professor( id=prof_id, first_name=first_name, last_name=last_name, ).save() course = m.Course.objects.with_id(uc.course_id) course.professor_ids = list(set(course.professor_ids) | {prof_id}) course.save() logging.info("Added new course professor %s (name: %s)" % (prof_id, new_prof_name)) elif uc_data.get('professor_id'): uc.professor_id = uc_data['professor_id'] else: uc.professor_id = None now = datetime.now() if uc_data.get('course_review'): # New course review data uc_data['course_review']['comment_date'] = now uc.course_review.update(**uc_data['course_review']) if uc_data.get('professor_review'): # New prof review data uc_data['professor_review']['comment_date'] = now uc.professor_review.update(**uc_data['professor_review']) uc.save() points_gained = uc.num_points - orig_points user.award_points(points_gained, view_helpers.get_redis_instance()) user.save() return util.json_dumps({ 'professor_review.comment_date': uc['professor_review'][ 'comment_date'], 'course_review.comment_date': uc['course_review']['comment_date'], 'points_gained': points_gained, })