Example #1
0
'registered' by importing them. The sub controllers need to
import the base blue-print from this file in order to be registered.
"""

__author__ = "Harshvardhan Gupta"

from datetime import datetime

from flask_login import current_user, login_required

from Sugar import JSONifiedNestableBlueprint
from extensions import db
from models import Error, Role, UserRoles
from .Misc import admin_misc_controller

admin_base_blueprint = JSONifiedNestableBlueprint('admin_api', __name__)

admin_base_blueprint.register_blueprint(admin_misc_controller)


# admin_base_blueprint.register_blueprint(admin_tests_controller)

@admin_base_blueprint.before_request
@login_required
def verify_admin():
    """
    Checks if the current user has an admin role.
    It also means that the user must be logged in.

    This function will be applied to all endpoints that use admin blueprint.
    :return:
Example #2
0
from flask import current_app, request
from flask_login import current_user, login_required

from Externals import Discourse
from Sugar import JSONifiedNestableBlueprint
from models import Error

discourse_blueprint = JSONifiedNestableBlueprint('Discourse', __name__)


@discourse_blueprint.route("/discourse_sso", methods=['POST'])
@login_required
def discourse_login():
    try:
        payload = request.args.get('sso')
        signature = request.args.get('sig')

        decoded = Discourse.parse_payload(payload, signature)
        query_string = Discourse.build_return_payload(decoded, current_user.id)

        url = f"{current_app.config['DISCOURSE_URL']}?{query_string}"
    except:
        return Error("Invalid query parameters provided", 403)()

    return {"url": url}
from flask import Response
from flask_login import current_user, login_required
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only, eagerload, undefer
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, requires_roles
from Util import Pinger
from extensions import db
from models import Choice, Error, Question, QuestionAttempt, Section, \
    SectionAttempt, Test, TestAttempt, AuditLog

__author__ = "Harshvardhan Gupta"

test_attempt_controller = JSONifiedNestableBlueprint("TestAttempt", __name__)


@test_attempt_controller.route('/tests/<test_id>/attempts/start',
                               methods=['Post'])
@login_required
def start_test(test_id):
    """
    Start a test.

    If an existing test_attempt that is not complete exists, it is returned.
    If not, if the user has access to the test, a new test attempt and section
    attempt(s) is created and returned.

    :param testID:
    :return: the id of the test attempt
from flask import request
from flask_login import current_user, login_required
from sqlalchemy import exc
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, requires_roles, \
    requires_validation
from extensions import db
from models import Error, PromoCode
from .req_val import PromoCodeInputs

promo_codes_controller = JSONifiedNestableBlueprint("PromoCodes", __name__)


@promo_codes_controller.route('/promo_codes/', methods=['GET'])
@requires_roles('admin')
def get_promo_codes():
    """
    Returns all available Promo Codes in database
    :return: [promo.todict()]
    """
    try:
        promo_codes = PromoCode.query.all()
        return promo_codes
    except NoResultFound:
        return Error('Invalid Promo Code', 400)()


@promo_codes_controller.route('/promo_codes/<code>', methods=['GET'])
@requires_roles('admin')
def get_promo_code(code):
Example #5
0
from flask import Flask, url_for, render_template, make_response, request
from Sugar import JSONifiedNestableBlueprint
from flask import url_for, render_template, make_response, jsonify
from models import TestAttempt, Test, Section, QuestionSection, Order, OrderTest, Question
from sqlalchemy import func, select, case
from Sugar import JSONifiedNestableBlueprint
from flask import request
from flask_login import current_user, login_required
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only

from flask import jsonify
import requests

__author__ = "Harshvardhan Gupta"
base_blueprint = JSONifiedNestableBlueprint("UIBASE", __name__)


@base_blueprint.route('/', methods=['Get'])
def status_page():
    """
    Just a function to echo current time.
    May be useful for testing if servers are up.
    :return: current date
    """
    r = make_response(render_template("UI/Pages/landing_page.html"))
    return r


@base_blueprint.route('/test', methods=['GET', 'POST'])
def test_listing():
from flask import Response
from flask_login import current_user, login_required
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound
from extensions import db

from Sugar import JSONifiedNestableBlueprint
from Util import Pinger

from models import (Choice, Error, Question, Section, Test, TestAttempt,
                    SectionAttempt)

__author__ = "Harshvardhan Gupta"

section_attmpt_ctrl = JSONifiedNestableBlueprint('section_attempt_controller',
                                                 __name__)


@section_attmpt_ctrl.route(
    '/tests/<testID>/sections/<sectionID>/attempts/finish', methods=["Post"])
@login_required
def finish_section(testID, sectionID):
    try:
        test_id, section_id, jumps_allowed, _, _ = Pinger.split_pinger_string()
    except:
        return Error("No Pinger", 403)()

    try:

        test_attempt = (TestAttempt.query.filter(
            TestAttempt.test_id == test_id).filter(
from flask import request
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, requires_validation
from controllers.rex import CookieHelper
from controllers.rex.CookieHelper import requires_corporate_cookies
from controllers.rex.TestAttempts.req_val import ApplicationStatusTypes, \
    UpdateApplicants, UpdateScore
from extensions import db
from models import Corporate, CorporateApplicants, Error, QuestionAttempt, \
    SectionAttempt, TestAttempt, TestAttemptReport, SixteenPReport

rex_testattempts_controller = JSONifiedNestableBlueprint('RexTestAttempt',
                                                         __name__)


@rex_testattempts_controller.route('/test/<test_id>/attempts/<date>',
                                   methods=['Get'])
@requires_corporate_cookies()
def get_overview(test_id, date):
    if not Corporate.can_access_test(CookieHelper.get_corporate_id(),
                                     test_id):
        return Error("No access", 403)()

    return (Corporate.get_test_performance(CookieHelper.get_corporate_id(),
                                           test_id, date))


@rex_testattempts_controller.route(
Example #8
0
from flask_login import current_user
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager

from Sugar import JSONifiedNestableBlueprint
from models import Course, Order, OrderCourse

courses_controller = JSONifiedNestableBlueprint("Courses", __name__)


@courses_controller.route('/courses', methods=['Get'])
def get_courses():
    """
    List all courses in the system.
    If user has purchased some, the courses will have 'is_purchased' key
    to true, else it will be false.

    If user has access to those courses by being in a college, the same thing
    applies.

    It also passes the query parameters received from the client
    as is , to the db queries. Useful for filtering

    """
    current_user_id = current_user.id if not current_user.is_anonymous else None

    # left outer join on course -> orders -> ordercourse. if user has a
    # paid order  it will be accessible by course.order.
    courses = (Course.query
               .outerjoin(OrderCourse,
                          OrderCourse.course_id == Course.id)
Example #9
0
from flask_login import current_user, login_required
from sqlalchemy import and_
from Sugar import cachify

from Sugar import JSONifiedNestableBlueprint
from models import Error, Section, Test, TestAttempt
from .Questions import questions_controller
from .SectionAttempts import section_attmpt_ctrl

__author__ = "Harshvardhan Gupta"

sections_controller = JSONifiedNestableBlueprint('Sections_controller',
                                                 __name__)
sections_controller.register_blueprint(questions_controller)
sections_controller.register_blueprint(section_attmpt_ctrl)


@sections_controller.route('/tests/<test_id>/sections', methods=['Get'])
@cachify(1800)
@login_required
def get_sections(test_id):
    """
    Get list of sections for a particular test.
    This requires the test attempt for the user to exist for the test

    :param test_id:
    :return:
    """
    sections = (Section.query.join(Test).join(
        TestAttempt,
        and_(TestAttempt.test_id == Test.id,
Example #10
0
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint
from models import Corporate, Error

corporates_controller = JSONifiedNestableBlueprint("Corporates", __name__)


@corporates_controller.route('/corporates/<path:corporate_slug>',
                             methods=['GET'])
def get_corporate(corporate_slug):
    try:
        corporate = Corporate.query \
            .filter(Corporate.slug == corporate_slug) \
            .one()
        return corporate
    except NoResultFound:
        return Error("Invalid Corporate Slug", 400)()
Example #11
0
from flask_login import current_user, login_required
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, cachify
from extensions import cache
from models import Choice, CodingCase, CodingLanguage, Error, Question, \
    TestAttempt
from .QuestionAttempts import qstn_attmpt_ctrl

__author__ = "Harshvardhan Gupta"

questions_controller = JSONifiedNestableBlueprint(
        'Questions_controller', __name__)

questions_controller.register_blueprint(qstn_attmpt_ctrl)


@cache.cached(timeout=6000)
def fetch_question(question_id):
    question = (Question.query
                .outerjoin(Question.choices)
                .outerjoin(CodingCase,
                           and_(Question.id == CodingCase.question_id,
                                CodingCase.viewable_with_question == True))
                .outerjoin(Question.allowed_languages)
                .options(
            load_only(Question.html, Question.rc_passage,
                      Question.coding_cases,
                      Question.type))
Example #12
0
from flask import Response
from json2html import json2html
from sqlalchemy.orm import contains_eager

from Sugar import JSONifiedNestableBlueprint, requires_roles
from models import (Order, PromoCode, User)

admin_misc_controller = JSONifiedNestableBlueprint("Admin MISC", __name__)


@admin_misc_controller.route('/misc/promo_metrics', methods=['GET'])
def get_admin_promo_metrics():
    """
    Get promocode->orders->users as a table.

    This takes in a complex json object and uses json2html to make it
    a readable table.

    :return: the json in table format as *HTML* format
    """

    query = (PromoCode.query.outerjoin(PromoCode.orders).outerjoin(
        Order.user).options(
            contains_eager(PromoCode.orders).load_only(
                Order.user_id, Order.status).contains_eager(
                    Order.user).load_only(User.email)).all())

    result = [promo.todict() for promo in query]

    for promo in result:
        cancelled_count = 0
Example #13
0
from flask import request

from Mail import CONTACT_US, Mail
from Sugar import JSONifiedNestableBlueprint, requires_validation
from .req_val import ContactUsInputs

misc_controller = JSONifiedNestableBlueprint('Misc', __name__)


@misc_controller.route("/misc/contact_us", methods=['Post'])
@requires_validation(ContactUsInputs)
def contact_us():
    """
    Receives query message and sends it to the email in the request,
    and also "*****@*****.**"

    """
    req = request.json
    del req['captcha_token']
    email = req['email']

    Mail([email, '*****@*****.**', '*****@*****.**'], req, req, req,
         CONTACT_US).send()
Example #14
0
from Sugar import JSONifiedNestableBlueprint
from .Users import rex_user_controller
from .TestAttempts import rex_testattempts_controller

base_blueprint = JSONifiedNestableBlueprint("REXBASE", __name__)

base_blueprint.register_blueprint(rex_user_controller)
base_blueprint.register_blueprint(rex_testattempts_controller)


@base_blueprint.route('', methods=['Post', 'Get'])
def echo_time():
    pass
Example #15
0
from flask import request
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, requires_validation
from extensions import db
from models import Choice, Error, Question
from .req_val import QuestionInputs

__author__ = "Harshvardhan Gupta"
# All endpoints will have sectionID in them, so it is prepended
# to the nestable controller

admin_sections_controller = JSONifiedNestableBlueprint("Admin Sections",
                                                       __name__)


@admin_sections_controller.route('/<sectionId>/questions', methods=['GET'])
def get_admin_section_questions(sectionId):
    """
    List Questions of a Section for Admin based on the Section ID
    :param sectionId:
    :return: questions
    """
    try:
        questions = Question.query \
            .filter(Question.section_id == sectionId)\
            .all()

        return questions
    except NoResultFound:  # section id is incorrect
        return Error('Invalid Section ID', 400)()
Example #16
0
from flask import request
from flask_login import current_user, login_required
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound

from Externals import Discourse
from Externals.Razorpay import Razorpay
from Sugar import JSONifiedNestableBlueprint, requires_validation
from extensions import db
from models import (Error, Order, OrderCourse, OrderTest, PromoCode, Test)
from models.Order import OrderStatusTypes
from .req_val import OrderCreateInputs

__author__ = "Harshvardhan Gupta"
orders_controller = JSONifiedNestableBlueprint("Orders", __name__)


@orders_controller.route('/orders', methods=['GET'])
@login_required
def get_orders():
    """
    List Orders for a User.

    Currently it lists test ids associated with the Order.
    If more items are added, all those will also need to be sent over.

    :return: [orders.todict()]
    """
    orders = (Order.query.filter_by(
        **request.args).outerjoin(OrderTest).outerjoin(Test).options(
            contains_eager(Order.tests).load_only(
Example #17
0
from controllers.apiv01.Corporates.Corporates import corporates_controller
from extensions import celery
from models import TestAttempt
from models.SixteenPReport import SixteenPReport
from .Colleges import colleges_controller
from .Courses import courses_controller
from .Discourse import discourse_blueprint
from .Misc import misc_controller
from .Orders import orders_controller
from .PromoCodes import promo_codes_controller
from .Tests import tests_controller
from .Users import user_controller

__author__ = "Harshvardhan Gupta"

base_blueprint = JSONifiedNestableBlueprint("BASE", __name__)

# base_blueprint.register_blueprint(admin_base_blueprint, url_prefix='/admin')
base_blueprint.register_blueprint(user_controller)
base_blueprint.register_blueprint(tests_controller)
base_blueprint.register_blueprint(promo_codes_controller)
base_blueprint.register_blueprint(colleges_controller)
base_blueprint.register_blueprint(orders_controller)
base_blueprint.register_blueprint(courses_controller)
base_blueprint.register_blueprint(discourse_blueprint)
base_blueprint.register_blueprint(misc_controller)
base_blueprint.register_blueprint(corporates_controller)

from flask import request, url_for

Example #18
0
from flask import current_app as app, redirect, request, session, url_for
from flask_login import current_user, login_required, login_user, logout_user
from itsdangerous import BadSignature, URLSafeSerializer
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound

from Mail import FORGOT_PASSWORD, Mail, SIGNUP_ACTIVATION, WELCOME_MAIL
from Sugar import JSONifiedNestableBlueprint, requires_validation
from controllers.rex import CookieHelper
from extensions import bcrypt, celery, db, mautic
from models import Corporate, Error, User
from .req_val import ChangePasswordInputs, ForgotPasswordInputs, LoginInputs, \
    ResendActivationInputs, ResetPasswordInputs, SignupInputs

user_controller = JSONifiedNestableBlueprint('User', __name__)


@user_controller.route('/user', methods=['GET'])
@login_required
def get_user():
    """
    Current User is determined by Flask Login based on the Session Cookie

    :return:
    """
    # print(session)

    fields = [c.name for c in User.__table__.c]

    # get all fields except
    fields = filter(lambda x: x not in ['password', 'is_active', 'type'],
Example #19
0
from flask import Response
from flask_login import current_user
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager
from sqlalchemy.orm.exc import NoResultFound

from extensions import db

from Sugar import JSONifiedNestableBlueprint
from Util import Pinger
from models import (Section, Test, SectionAttempt, TestAttempt, Error,
                    QuestionAttempt)
from datetime import datetime

PingController = JSONifiedNestableBlueprint("Ping Controller", __name__)


@PingController.route(
    "/tests/<testID>/sections/<int:sectionID>/questions/<int:questionID>/attempts/ping",
    methods=["Post"])
def ping(testID, sectionID, questionID):
    """
    Perform 1 ping.
    The time spent on each section will be reduced by the Pinger's duration
    value.
    (Read how the logic works for sectional jumps vs non sectional jumps in the
    comments below).

    If all the requests succeed, then the pinger gets a new cookie with an
    updated time.
    If not, this operation will not happen, making future requests impossible.
Example #20
0
from Sugar import JSONifiedNestableBlueprint
from models import Test
from .Sections import admin_sections_controller

admin_tests_controller = JSONifiedNestableBlueprint("Admin Tests", __name__)
admin_tests_controller.register_blueprint(admin_sections_controller,
                                          url_prefix='/sections')


@admin_tests_controller.route('/tests', methods=['GET'])
def get_admin_tests():
    """
    List of existing Tests
    :return:
    """
    return Test.query.all()
Example #21
0
from flask import request
from flask_login import current_user, login_required
from sqlalchemy import and_
from sqlalchemy.orm import contains_eager, load_only
from sqlalchemy.orm.exc import NoResultFound

from Sugar import JSONifiedNestableBlueprint, cachify
from models import Error, Order, OrderTest, Test, TestAttempt, Section, \
    Question
from .Sections import sections_controller
from .TestAttempts import test_attempt_controller

from .Pinger import PingController

tests_controller = JSONifiedNestableBlueprint("Tests", __name__)

tests_controller.register_blueprint(test_attempt_controller)

tests_controller.register_blueprint(sections_controller)

tests_controller.register_blueprint(PingController)


@tests_controller.route('/tests', methods=['Get'])
def get_tests():
    """
    List all tests in the system.
    If user has purchased some, the tests will have 'is_purchased' key
    to true, else it will be false.

    If user has access to those tests by being in a college, the same thing