Beispiel #1
0
def create_master_secret(app, is_staging, created_app_name):
    """
    Creates a master secret.

    :param app: app creating the secret
    :type app: str

    :param is_staging: whether app is a staging app
    :type is_staging: bool

    :param created_app_name: app to create master secret for
    :type created_app_name: str

    :return: tuple of two randomly generated 64-character secrets.

    """
    if app != "buildserver" or is_staging:
        abort(403)  # only buildserver running in prod can create new apps
    with connect_db() as db:
        out = db(
            "SELECT public_value, staging_value FROM secrets WHERE app=%s AND name='MASTER'",
            [created_app_name],
        ).fetchone()
        if out is not None:
            return list(out)
        out = new_secret(), new_secret()
        db(
            "INSERT INTO secrets (app, name, public_value, staging_value) VALUES (%s, %s, %s, %s)",
            [created_app_name, "MASTER", *out],
        )
    return out
Beispiel #2
0
def create_master_secret(app, is_staging, created_app_name):
    if app != "buildserver" or is_staging:
        abort(403)  # only buildserver running in prod can create new apps
    with connect_db() as db:
        out = db(
            "SELECT public_value, staging_value FROM secrets WHERE app=%s AND name='MASTER'",
            [created_app_name],
        ).fetchone()
        if out is not None:
            return list(out)
        out = new_secret(), new_secret()
        db(
            "INSERT INTO secrets (app, name, public_value, staging_value) VALUES (%s, %s, %s, %s)",
            [created_app_name, "MASTER", *out],
        )
    return out
Beispiel #3
0
def submit():
    caption = str(request.form["caption"])
    if len(caption) > MAX_CAPTION_LEN:
        abort(
            413,
            f"Your caption is too long - it should be at most {MAX_CAPTION_LEN} characters.",
        )
    dice = loads(request.form["dice"])
    dice_list = []
    for svg in dice:
        if not isinstance(svg, str):
            abort(401)
        dice_list.append(svg)
    del dice
    if len(dice_list) != NUM_DICE:
        abort(401)
    group = get_group(get_endpoint("cs61a") + "/" + ASSIGNMENT)
    with connect_db() as db:
        for member in group:
            db("DELETE FROM designs WHERE email=(%s)", [member])
        email = group[0]
        db(
            "INSERT INTO designs (id, created_time, email, caption, dice, endpoint) VALUES (%s, %s, %s, %s, %s, %s)",
            [
                new_secret(),
                int(time()),
                email,
                caption,
                dumps(dice_list),
                get_endpoint("cs61a"),
            ],
        )

    return dict(success=True, group=group)
Beispiel #4
0
    def okpy_batch_grade_impl():
        data = request.json
        subm_ids = data["subm_ids"]
        assignment = data["assignment"]
        access_token = data["access_token"]

        if assignment == "test":
            return "OK"

        assignment: Optional[Assignment] = Assignment.query.get(assignment)
        if not assignment or assignment.endpoint != get_endpoint(
            course=assignment.course
        ):
            abort(404, "Unknown Assignment")

        if len(subm_ids) / assignment.batch_size > 50:
            abort(
                405,
                "Too many batches! Please set the batch_size so that there are <= 50 batches.",
            )

        job_secrets = [new_secret() for _ in subm_ids]
        queue_time = int(time.time())

        jobs = [
            Job(
                assignment_secret=assignment.assignment_secret,
                backup=backup_id,
                status="queued",
                job_secret=job_secret,
                external_job_id=new_secret(),
                access_token=access_token,
                queued_at=queue_time,
            )
            for backup_id, job_secret in zip(subm_ids, job_secrets)
        ]
        db.session.bulk_save_objects(jobs)
        db.session.commit()

        trigger_jobs(
            assignment_id=assignment.assignment_secret, jobs=job_secrets, noreply=True
        )

        return dict(jobs=[job.external_job_id for job in jobs])
Beispiel #5
0
def gen_env_variables(app: App, pr_number: int):
    # set up and create database user
    database = app.name.replace("-", "_")
    with connect_db() as db:
        db_pw = db(
            "SELECT mysql_pw FROM mysql_users WHERE app=(%s)", [app.name]
        ).fetchone()
        if db_pw is None:
            db_pw = new_secret()
            # unable to use placeholders here, but it's safe because we control the app.name and db_pw
            db(f"CREATE DATABASE IF NOT EXISTS {database}")
            db(f'CREATE USER "{app.name}"@"%%" IDENTIFIED BY "{db_pw}";')
            db(f"GRANT ALL ON {database}.* TO '{app}'@'%%'")
            db("FLUSH TABLES mysql.user")
            db(
                "INSERT INTO mysql_users (app, mysql_pw) VALUES (%s, %s)",
                [app.name, db_pw],
            )
        else:
            db_pw = db_pw[0]

    if app.config["deploy_type"] == "hosted":
        database_url = sqlalchemy.engine.url.URL(
            drivername="mysql",
            host=DB_IP_ADDRESS,
            username=app.name,
            password=db_pw,
            database=database,
        ).__to_string__(hide_password=False)
    elif app.config["deploy_type"] in CLOUD_RUN_DEPLOY_TYPES:
        database_url = sqlalchemy.engine.url.URL(
            drivername="mysql+pymysql",
            username=app.name,
            password=db_pw,
            database=database,
            query={"unix_socket": "{}/{}".format("/cloudsql", DB_INSTANCE_NAME)},
        ).__to_string__(hide_password=False)
    else:
        database_url = None

    # set up the remaining secrets
    return dict(
        ENV="prod",
        DATABASE_URL=database_url,
        INSTANCE_CONNECTION_NAME=DB_INSTANCE_NAME,
        **(
            dict(APP_MASTER_SECRET=gen_master_secret(app, pr_number))
            if "rpc" in app.config["permissions"]
            else {}
        ),
        **(
            load_all_secrets(created_app_name=app.name)
            if pr_number == 0 and "rpc" in app.config["permissions"]
            else {}
        ),
    )
Beispiel #6
0
    def create_assignment_rpc(course, name, file, command, batch_size,
                              grading_base):
        assignment: Assignment = Assignment.query.filter_by(
            name=name, course=course,
            endpoint=get_endpoint(course=course)).one_or_none()

        if not assignment:
            assignment = Assignment(
                name=name,
                assignment_secret=new_secret(),
                course=course,
                endpoint=get_endpoint(course=course),
            )
            db.session.add(assignment)

        assignment.file = file
        assignment.command = command
        assignment.last_modified = int(time.time())
        assignment.batch_size = batch_size
        assignment.grading_base = grading_base
        db.session.commit()

        return assignment.assignment_secret