예제 #1
0
def config():
    auth_result = authenticate(app)
    if not (isinstance(auth_result, str) and auth_result == "Authorized!"):
        return auth_result

    with connect_db() as db:
        gscope: List[Tuple[str, str]] = db(
            "SELECT name, gs_code FROM gscope",
            [],
        ).fetchall()
        adjustments: List[Tuple[str, str, str]] = db(
            "SELECT hashed, url, sheet FROM adjustments",
            [],
        ).fetchall()

    return html(
        """
    <h1>Grade Display Config</h1>
    <p>
        Add a Gradescope assignment:
        """
        + make_row(
            """<input name="name" placeholder="Shortname (no spaces!)" />
            <input name="gs_code" placeholder="Gradescope code" />
        """,
            url_for("create_assign"),
            "Submit",
        )
        + """
    </p>
    <p>
        Add an adjustments sheet:
        """
        + make_row(
            """<input name="url" placeholder="Full URL" />
            <input name="sheet" placeholder="Sheet Name" />
        """,
            url_for("add_adjustments"),
            "Submit",
        )
        + """
    </p>
    """
        + "".join(
            "<p>" + make_row(f"{name} ({gs_code})", url_for("delete_assign", name=name))
            for name, gs_code in gscope
        )
        + "".join(
            "<p>"
            + make_row(
                f"Adjustments: {url} ({sheet})",
                url_for("delete_adjustments", hashed=hashed),
            )
            for hashed, url, sheet in adjustments
        )
    )
예제 #2
0
 def super_clients():
     if not is_staff(MASTER_COURSE):
         return ""
     with connect_db() as db:
         ret = db("SELECT client_name, creator, unused FROM super_auth_keys"
                  ).fetchall()
     super_client_names = [
         make_row(
             f'{client_name}, created by {creator} {"(unused)" if unused else ""} ',
             url_for("revoke_super_key", client_name=client_name),
         ) for client_name, creator, unused in ret
     ]
     return f"""
         <h3>Super-Clients</h3>
         <p>
         Warning - the API keys for these clients are extremely sensitive, 
         as they can access <i>any</i> course's data. Only use them for 61A-hosted apps, 
         and reset them whenever a head TA leaves course staff.
         </p>
         Create new super-client and obtain secret key:
         <form action="{url_for("create_super_key")}" method="post">
             <input name="client_name" type="text" placeholder="client_name">
             <input type="submit">
         </form>
     """ + "<p>".join(super_client_names)
예제 #3
0
 def admin_data(course):
     with connect_db() as db:
         ret = db(
             "SELECT email, name, course, creator FROM course_admins WHERE course=(%s)",
             [course],
         ).fetchall()
     admin_names = [
         make_row(
             f'{name} (<a href="mailto:{email}">{email}</a>), added by {creator} ',
             url_for("remove_admin", course=course, email=email),
         ) for email, name, course, creator in ret
     ]
     add_admin = f"""
         Add new course administrator:
         <form action="{url_for("add_admin", course=course)}" method="post">
             <input name="email" type="email" placeholder="Email address">
             <input type="submit">
         </form>
     """
     with connect_db() as db:
         ret = db(
             "SELECT url, sheet FROM course_permissions WHERE course=(%s)",
             [course]).fetchall()
     perms_sheet = [
         make_row(
             f'<a href="{url}">{sheet} ({url})</a>',
             url_for("unset_granular_spreadsheet", course=course),
         ) for url, sheet in ret
     ]  # there should only be 0-1 perms sheets
     add_perms_sheet = f"""
         Add granular permissions sheet (first column should be email, the rest should be permission names):
         <form action="{url_for("set_granular_spreadsheet", course=course)}" method="post">
             <input name="url" placeholder="URL">
             <input name="sheet" placeholder="Sheet Name">
             <input type="submit">
         </form>
     """
     return ("<h3>Admins</h3>" + add_admin + "<p>".join(admin_names) +
             "<br>" + "<h3>Granular Permissions</h3>" + add_perms_sheet +
             "<p>".join(perms_sheet))
예제 #4
0
    def slack_help(course):
        with connect_db() as db:
            workspace = db(
                "SELECT workspace FROM slack_config WHERE course=(%s)",
                [course]).fetchone()
            workspace = workspace[0] if workspace else ""

            registered_channels = db(
                "SELECT purpose, channel, channel_id FROM slack_channels WHERE course=(%s)",
                [course],
            ).fetchall()

        try:
            channels = list_channels(course=course)
        except:
            registration = """
            To register Slack channels, first go to 
            <a href="https://slack.cs61a.org">slack.cs61a.org</a> 
            to add the bot to your workspace.
            """
        else:
            channels = [
                f"<option value=\"{channel['name']}\">{channel['name']}</option>"
                for channel in channels
            ]
            registration = f"""
                Register a new Slack channel.
                <form action="/slack/{course}/register_channel" method="post">
                    <input name="purpose" type="text" placeholder="Purpose">
                    <select name="channel">
                        {channels}
                    </select>
                    <input type="submit">
                </form>
            """

        registered_channels_list = "<p>".join(
            make_row(
                f"{purpose} associated with #{channel} (id: {channel_id})",
                url_for("remove_channel", course=course, purpose=purpose),
            ) for purpose, channel, channel_id in registered_channels)

        return f"""
예제 #5
0
파일: main.py 프로젝트: 61a-ide/cs61a-apps
def index():
    if not is_staff(get_course()):
        return login()
    with connect_db() as db:
        sources = db(
            "SELECT url, sheet, secure FROM sources WHERE course=%s", [get_course()]
        ).fetchall()

    insert_fields = """<input placeholder="Spreadsheet URL" name="url"></input>
        <input placeholder="Sheet Name" name="sheet"></input>
        <label>
            <input type="checkbox" name="secure"></input>
            Require Authentication
        </label>"""

    sources = "<br/>".join(
        make_row(
            f'<a href="{url}">{url}</a> {sheet} (Secure: {secure})'
            f'<input name="url" type="hidden" value="{url}"></input>'
            f'<input name="sheet" type="hidden" value="{sheet}"></input>',
            url_for("remove_source"),
        )
        for url, sheet, secure in sources
    )

    return html(
        f"""
    <h2>Course: <code>{get_course()}</code></h2>
    Each spreadsheet should be shared with the 61A service account
    <a href="mailto:[email protected]">
        [email protected]</a>.
    They should have three columns with the headers: "URL", "Shortlink", and "Creator".
    <p>
    Visit <a href="{url_for("refresh")}">{url_for("refresh")}</a> (no auth required) 
    after adding a link to synchronize with the spreadsheets.

    <h3>Sources</h3>
    {sources}
    <h3>Add Sources</h3>
    {make_row(insert_fields, url_for("add_source"), "Add")}
    """
    )
예제 #6
0
 def client_data(course):
     with connect_db() as db:
         ret = db(
             "SELECT email, name, course, creator FROM course_admins WHERE course=(%s)",
             [course],
         ).fetchall()
     admin_names = [
         make_row(
             f'{name} (<a href="mailto:{email}">{email}</a>), added by {creator} ',
             url_for("remove_admin", course=course, email=email),
         ) for email, name, course, creator in ret
     ]
     create_client = f"""
         Add new course administrator:
         <form action="{url_for("add_admin", course=course)}" method="post">
             <input name="email" type="email" placeholder="Email address">
             <input type="submit">
         </form>
     """
     return "<h3>Admins</h3>" + create_client + "<p>".join(admin_names)
예제 #7
0
 def client_data(course):
     with connect_db() as db:
         ret = db(
             "SELECT client_name, creator, unused FROM auth_keys WHERE course=(%s)",
             [course],
         ).fetchall()
     client_names = [
         make_row(
             f'{client_name}, created by {creator} {"(unused)" if unused else ""} ',
             url_for("revoke_key", course=course, client_name=client_name),
         ) for client_name, creator, unused in ret
     ]
     create_client = f"""
         Create new client and obtain secret key:
         <form action="{url_for("create_key", course=course)}" method="post">
             <input name="client_name" type="text" placeholder="client_name">
             <input type="submit">
         </form>
     """
     return "<h3>Clients</h3>" + create_client + "<p>".join(client_names)
예제 #8
0
    def domains_help(course):
        with connect_db() as db:
            ret = db("SELECT domain FROM domains_config WHERE course=(%s)",
                     [course]).fetchall()
        client_names = [
            make_row(domain,
                     url_for("remove_domain", domain=domain, course=course))
            for domain, in ret
        ]
        register_domain = f"""
            Register new domain:
            <form action="/domains/{course}/register_domain" method="post">
                <input name="domain_name" type="text" placeholder="seating.cs61a.org">
                <input type="submit">
            </form>

            View the status of your domain setup at 
            <a href="https://domains.cs61a.org/">domains.cs61a.org</a>
            <br />
        """
        return "<h3>Domains</h3>" + register_domain + "<p>".join(client_names)
예제 #9
0
    def add_course():
        if not is_staff(MASTER_COURSE):
            return ""
        with connect_db() as db:
            courses = db("SELECT course, endpoint FROM courses").fetchall()
        courses = [
            make_row(
                "{} ({}), at endpoint {}".format(prettify(course), course,
                                                 endpoint),
                url_for("remove_course", course=course),
            ) for course, endpoint in courses
        ]

        return """
            <h2>Admin</h2>
            <h3>Courses</h3>
            Activate Auth for a new course (method only available to 61A admins):
            <form action="/api/add_course" method="post">
                <input name="course" type="text" placeholder="course name">
                <input name="endpoint" type="text" placeholder="OKPy endpoint">
                <input type="submit">
            </form>
        """ + "<p>".join(courses)