def _process(self): if "friend computer please build" not in self._message.lower(): return if "cs61a" != self._course: return users = requests.get("https://slack.com/api/users.list", params={ "token": self._bot_token }).json() for member in users["members"]: if member["id"] == self._event["user"]: sender_email = member["profile"].get("email") break if not sender_email or not is_admin(course="cs61a", email=sender_email): return match = re.search(REGEX_TEMPLATE, self._message) if not match: return try: pr = int(match.group("path")) except ValueError: return trigger_build_sync(pr_number=pr, noreply=True) self.reply = ":building_construction: Build triggered!"
def index(): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): abort(401) with connect_db() as db: apps = db("SELECT app FROM services WHERE pr_number=0", []).fetchall() pr_apps = db( "SELECT app, pr_number FROM services WHERE pr_number>0 ORDER BY pr_number DESC", [], ).fetchall() return html( f""" This service manages the deployment of the 61A website and various apps. {"".join(f''' <form action="/deploy_prod_app"> <input type="submit" name="app" value="{app}" /> </form> ''' for [app] in apps)} {"".join(f''' <form action="/trigger_build"> <input type="hidden" name="app" value="{app}" /> <input type="hidden" name="pr_number" value="{pr_number}" /> <input type="submit" value="{app + "-pr" + str(pr_number)}" /> </form> ''' for [app, pr_number] in pr_apps)} <form action="/delete_unused_services" method="post"> <input type="submit" value="Delete unused services" /> </form> """ )
def create_secret(service): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): abort(401) if service not in list_services(): abort(404) out = reversed([ entry["timestamp"] + " " + escape(entry["textPayload"]) for entry in loads( sh( "gcloud", "logging", "read", f"projects/cs61a-140900/logs/run.googleapis.com AND resource.labels.service_name={service}", "--limit", "100", "--format", "json", capture_output=True, )) if "textPayload" in entry ]) return "<pre>" + "\n".join(map(str, out)) + "</pre>"
def delete_unused_services_handler(): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): return login() delete_unused_services() return redirect(url_for("index"))
def deploy_prod_app(): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): abort(401) app = request.args["app"] deploy_prod_app_sync(target_app=app, noreply=True) return html(f"Deploying <code>{app}</code> from master!")
def index(): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): abort(401) service_list = "\n".join( f"<p /><a href={url_for('create_secret', service=service)}>{service}</a>" for service in list_services()) return f"""
def is_admin(email, course=None): """Returns whether or not an email address belongs to an admin for the given course, using :meth:`~common.rpc.auth.is_admin`. :param email: the email address in question :type email: str :param course: the course code, such as "cs61a", inferred using :meth:`~common.course_config.get_course` if omitted :type course: str :return: ``True`` if the user is an admin, ``False`` otherwise """ if getenv("ENV") != "prod": return True if not course: course = get_course() return auth.is_admin(email=email, course=course, force_course=course)
def trigger_build(): if not is_staff("cs61a"): return login() email = get_user()["email"] if not is_admin(course="cs61a", email=email): abort(401) if "app" in request.args: target = request.args["app"] else: target = None pr_number = int(request.args["pr_number"]) g = Github(get_secret(secret_name="GITHUB_ACCESS_TOKEN")) repo = g.get_repo(GITHUB_REPO) pr = repo.get_pull(pr_number) if DO_NOT_BUILD in [l.name for l in pr.labels]: return html( f"PR <code>{pr_number}</code> has a DO NOT BUILD label on it, so it cannot be built. Remove this label to build the PR." ) trigger_build_sync(pr_number=pr_number, target_app=target, noreply=True) return html(f"Building PR <code>{pr_number}</code>!")
def wrapped(*args, **kwargs): if not (is_staff("cs61a") and is_admin(email=get_user()["email"])): return login() return func(*args, **kwargs)
def query(): try: if is_logged_in(): user = get_user() email = user["email"] target = request.args.get("target", None) admin = True if DEV else is_admin(course=get_course(), email=email) if is_staff(get_course()): if target: email = target else: show_all_students = has_access_to_all_grades() students = [] with connect_db() as db: lookup = db( "SELECT shortData FROM students WHERE courseCode=%s", [get_course()], ).fetchall() for row in lookup: parsed = json.loads(row[0]) if show_all_students or parsed.get("TA", "") in ( "", email, ): students.append(parsed) return jsonify({ "success": True, "isStaff": True, "isAdmin": admin, "canExportGrades": show_all_students, "allStudents": students, "email": user["email"], "name": user["name"], "lastUpdated": last_updated(), }) with connect_db() as db: [short_data, data] = db( "SELECT shortData, data FROM students WHERE courseCode=%s AND email=%s", [get_course(), email], ).fetchone() [header ] = db("SELECT header FROM headers WHERE courseCode=%s", [get_course()]).fetchone() short_data = json.loads(short_data) if not (email == user["email"] or admin or short_data.get( "TA", "") in ("", user["email"])): return jsonify({"success": False, "retry": False}) data = json.loads(data) header = json.loads(header) return jsonify({ "success": True, "header": header, "data": data, "email": short_data["Email"], "name": short_data["Name"], "SID": short_data["SID"], "ta": short_data.get("TA", ""), "lastUpdated": last_updated(), }) else: return jsonify({"success": False, "retry": True}) except Exception: pass return jsonify({"success": False, "retry": False})