def answer_vote(answer_id): if request.method == 'GET': return render_json(vote.get_answer_vote(answer_id)) json = request.get_json(silent=True) if json is None: return abort(400) vote_data = json['vote'] return render_json(vote.do_answer_vote(answer_id, vote_data))
def get_my_profile(): """ Returns the logged in user's profile or a JSON with `unauthorized: true` """ if isinstance(g.user, User): return render_json(g.user.to_json()) else: return render_json({'unauthorized': True})
def category_search(): json = request.get_json(silent=True) if not json or 'query' not in json or len(str(json['query'])) == 0: return render_error('Bad query') return render_json({'results': search_category(query=str(json['query']))})
def mark_notifications_status(notifications, status): """ Marks a list of notification IDs as seen. Requires authorized user in session """ if not isinstance(g.user, User): return render_error('Unauthorized'), 401 if status == NotificationStatus.SEEN: # Basically we won't want "read" messages going to # "seen" state Notification.query.filter( Notification.recipient == g.user, Notification.uuid.in_(notifications), Notification.read == NotificationStatus.UNSEEN).update( {'read': NotificationStatus.SEEN}, synchronize_session=False) else: Notification.query.filter(Notification.recipient == g.user, Notification.uuid.in_(notifications)).update( {'read': status}, synchronize_session=False) db.session.commit() return render_json({'status': status.value})
def auth_method_list(): if g.user is None: return abort(401) methods = auth.get_auth_methods(user=g.user) return render_json({'methods': methods})
def notification_status(): unseen_notifs = notifications.get_unseen_notification_count() if not isinstance(unseen_notifs, int): return unseen_notifs return render_json({'unseen_count': unseen_notifs})
def delete_answer_comment(answer_id, comment_id): try: comment.delete_answer_comment(comment_id) except PermissionError: return abort(403) response = {'comment_id': comment_id, 'deleted': True} return render_json(response)
def webapn_get_identification(): if not isinstance(g.user, User): return abort(401) # Generate a short-term expiring token authorization_token = webapn.generate_temporary_id() return render_json({'token': authorization_token})
def merge_users(): source_ids = request.form['source_ids'] target_id = request.form['target_id'] admin_controller.merge_users(source_ids, target_id) return render_json({ 'source_ids': source_ids, 'target_id': target_id, 'merge_users': True })
def get_profile(user_id): """ Returns a user's user_id """ user = User.query.filter_by(id=user_id).first() if user is None: return render_error('user not found'), 400 else: return render_json(user.to_json())
def get_answer_comment(answer_id, comment_id): answer_comment = comment.get_answer_comment(comment_id) rendered_text = markdown.render_markdown.delay(answer_comment.text).wait() if rendered_text is None: return abort(500) response = answer_comment.to_json() response["rendered_text"] = rendered_text return render_json(response)
def add_webpush_device(subscription_json): if not isinstance(g.user, User): return abort(401) if 'endpoint' not in subscription_json or\ 'keys' not in subscription_json or\ 'auth' not in subscription_json['keys'] or\ 'p256dh' not in subscription_json['keys']: return abort(400) if len(g.user.push_devices) > notifications['max_push_devices']: return abort(429) endpoint = subscription_json['endpoint'] auth = subscription_json['keys']['auth'] client_public_key = subscription_json['keys']['p256dh'] # Add missing base64 padding auth += '=' * (-len(auth) % 4) client_public_key += '=' * (-len(client_public_key) % 4) # This is the expected length of encoded pub key if len(client_public_key) != 88: abort(400) # For why 24 see models.PushDevice # This is the expected length of the auth key if len(auth) != 24: return abort(400) # Validate public key try: public_key = ec.EllipticCurvePublicNumbers.from_encoded_point( ec.SECP256R1(), urlsafe_b64decode(client_public_key) ) except: return abort(400) # Validate endpoint try: url = urlparse(endpoint) if url.scheme != 'https': return abort(400) except: return abort(400) push_device = PushDevice(user_id=g.user.id, endpoint=endpoint, auth=auth, client_pub=client_public_key) db.session.add(push_device) db.session.commit() return render_json({'device_id': push_device.id})
def get_followers(user_id, page): user = User.query.filter_by(id=user_id).first() if not isinstance(user, User): return render_error('Nonexistent ID'), 404 followers = user.followers.filter_by(following_public=True).paginate(page, user_list['page_len'], error_out=False) return render_json({ 'data': [follower.to_json(current_user=g.user) for follower in followers.items], 'are_more': followers.has_next })
def auth_login_jwt(): json = request.get_json(silent=True) # JSON parsing failed if not json or 'token' not in json: return render_error('bad json') jwt_errors = auth.set_user_jwt(json['token'], json.get('profile')) if jwt_errors is not None: return jwt_errors else: return render_json({'user_id': g.user.id})
def mark_notification_status(notification_id, status): """ Marks a give notification as read. """ if not isinstance(g.user, User): return render_error('Unauthorized'), 401 notifications = Notification.query.\ filter_by(recipient_id=g.user.id, uuid=notification_id) notifications.update({'read': status}) db.session.commit() return render_json({'status': status.value})
def publish_post(): if g.user is None: return abort(403) title = request.form.get('post-title', '').encode('utf-8') body = request.form.get('post-body', '').encode('utf-8') categories = request.form.getlist('post-categories') redirect_url = post.create_post( title=title, body=body, categories=categories ) if request.accept_mimetypes.accept_json: return render_json({ 'redirect': redirect_url }) else: return redirect(redirect_url)
def publish_post(): if g.user is None: return abort(403) title = request.form.get('post-title', '').encode('utf-8') body = request.form.get('post-body', '').encode('utf-8') categories = request.form.getlist('post-categories') ppcg_id = request.form.get('post-ppcg-id', None, type=int) redirect_url = post.create_post(title=title, body=body, categories=categories, ppcg_id=ppcg_id) # only should accept JSON if request.headers.get('Accept', '') == 'application/json': return render_json({'redirect': redirect_url}) else: return redirect(redirect_url)
def mark_all_notifications_status(status): """ Marks all notifications as seen. Requires authorized user """ if not isinstance(g.user, User): return render_error('Unauthorized'), 401 if status == NotificationStatus.SEEN: Notification.query.\ filter_by(recipient=g.user, read=NotificationStatus.UNSEEN).\ update({'read': status}) else: Notification.query.\ filter_by(recipient=g.user).\ update({'read': status}) db.session.commit() return render_json({'status': status.value})
def remove_auth_method(id, user): """ Removes auth method for user """ auth_tokens = UserAuthToken.query.filter_by(user_id=user.id).all() if len(auth_tokens) <= 1: # You can't remove auth token if you only have 1 return render_error('not enough tokens'), 412 selected_token = next( (auth_token for auth_token in auth_tokens if auth_token.id == id), None) if not isinstance(selected_token, UserAuthToken): return render_error('invalid method'), 404 db.session.delete(selected_token) db.session.commit() return render_json({'id': id})
def publish_answer(): if g.user is None: return abort(403) post_id = request.form['post_id'] # Important parts code = b64decode(request.form['code']) lang_id = request.form.get('lang_id', None) lang_name = request.form.get('lang_name', None) encoding = request.form.get('encoding', 'utf-8') commentary = request.form.get('commentary', "") redirect_url = answer.create_answer(post_id, code, commentary, lang_id=lang_id, lang_name=lang_name, encoding=encoding) if request.headers.get('Accept', '') == 'application/json': return render_json({'redirect': redirect_url}) else: return redirect(redirect_url)
def unfollow(source_user_id, target_user_id): """ Makes 1st param unfollow the 2nd param """ if source_user_id == target_user_id: return render_error('cannot follow oneself'), 400 source_user = User.query.filter_by(id=source_user_id).first() target_user = User.query.filter_by(id=target_user_id).first() if not isinstance(g.user, User): return render_error('Unauthorized'), 401 if source_user is None or target_user is None: return render_error('source user or target user doesn\'t exist'), 400 if source_user.id != g.user.id: return render_error('Forbidden'), 403 source_user.unfollow(target_user) db.session.commit() return render_json({ 'following': False })
def get_answer_comment(answer_id, comment_id): answer_comment = comment.get_answer_comment(comment_id) response = answer_comment.to_json() return render_json(response)
def get_post_comment(post_id, comment_id): post_comment = comment.get_post_comment(comment_id) response = post_comment.to_json() return render_json(response)
def get_post_comments_page(post_id, parent_id, page_id, initial_offset): comments = comment.get_post_comments_page(post_id, parent_id, page_id, initial_offset) return render_json(comments)
def edit_answer_comment(answer_id, comment_id): comment_text = request.form["comment_text"] edited_comment = comment.edit_answer_comment(comment_id, comment_text) return render_json(edited_comment.to_json())
def write_answer_comment(answer_id): comment_text = request.form["comment_text"] parent_comment = request.form.get("parent_comment", None) new_comment = comment.create_answer_comment(answer_id, parent_comment, comment_text) return render_json(new_comment.to_json())
def answer_votes(answer_id): return render_json(vote.get_answer_vote_breakdown(answer_id))
def post_votes(post_id): return render_json(vote.get_post_vote_breakdown(post_id))
def get_canonical_post_url(post_id): matched_post = post.get_post(post_id=post_id) if matched_post is None: return abort(404) url = canonical_host + url_for('get_post', post_id=post_id, title=slugify(matched_post.title)) return render_json({"url": url})
def edit_post(post_id): try: return render_json(post.revise_post(post_id, request.get_json()).to_json()) except PermissionError: return abort(403)