-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored the control panel and workspace reload #489
Changes from all commits
07b0a70
3bbd272
27394a5
0be1542
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from flask_restx import Namespace, Resource | ||
from flask import request, render_template, url_for, abort | ||
from CTFd.utils.user import get_current_user | ||
from CTFd.utils.decorators import authed_only | ||
from ...utils import get_current_container, container_password | ||
from ...utils.workspace import exec_run, start_on_demand_service | ||
|
||
|
||
workspace_namespace = Namespace( | ||
"workspace", description="Endpoint to manage workspace iframe urls" | ||
) | ||
|
||
|
||
@workspace_namespace.route("") | ||
class view_desktop(Resource): | ||
@authed_only | ||
def get(self): | ||
user_id = request.args.get("user") | ||
password = request.args.get("password") | ||
service = request.args.get("service") | ||
|
||
if not service: | ||
return { "active": False } | ||
|
||
|
||
if user_id and not password and not is_admin(): | ||
abort(403) | ||
|
||
user = get_current_user() if not user_id else Users.query.filter_by(id=int(user_id)).first_or_404() | ||
container = get_current_container(user) | ||
if not container: | ||
return { "active": False } | ||
|
||
|
||
if service == "desktop": | ||
interact_password = container_password(container, "desktop", "interact") | ||
view_password = container_password(container, "desktop", "view") | ||
|
||
if user_id and password: | ||
if not hmac.compare_digest(password, interact_password) and not hmac.compare_digest(password, view_password): | ||
abort(403) | ||
password = password[:8] | ||
else: | ||
password = interact_password[:8] | ||
|
||
view_only = user_id is not None | ||
service_param = "~".join(("desktop", str(user.id), container_password(container, "desktop"))) | ||
|
||
vnc_params = { | ||
"autoconnect": 1, | ||
"reconnect": 1, | ||
"reconnect_delay": 200, | ||
"resize": "remote", | ||
"path": url_for("pwncollege_workspace.forward_workspace", service=service_param, service_path="websockify"), | ||
"view_only": int(view_only), | ||
"password": password, | ||
} | ||
iframe_src = url_for("pwncollege_workspace.forward_workspace", service=service_param, service_path="vnc.html", **vnc_params) | ||
else: | ||
iframe_src = f"/workspace/{service}/" | ||
|
||
if start_on_demand_service(user, service) is False: | ||
return { "active": False } | ||
|
||
return { | ||
"iframe_src": iframe_src, | ||
"service": service, | ||
"active": True | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,29 @@ | ||
const broadcast = new BroadcastChannel('broadcast'); | ||
|
||
broadcast.onmessage = (event) => { | ||
if (event.data.msg === 'New challenge started') { | ||
if (window.location.pathname === '/workspace/code') { | ||
window.location.reload(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason code uses a window reload, while the desktop gets/sets the iframe url? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i cant figure out why reloading the iframe does not work. as the iframe url seams to be the same. |
||
} | ||
else if (window.location.pathname === '/workspace/desktop') { | ||
get_and_set_iframe_url() | ||
} | ||
} | ||
}; | ||
function get_and_set_iframe_url() { | ||
// check if the window location pathname starts with /workspace/ and set the rest of the path as an variable service | ||
const service = window.location.pathname.startsWith('/workspace/') ? window.location.pathname.substring(11) : ''; | ||
fetch("/pwncollege_api/v1/workspace?service=" + service) | ||
.then(response => response.json()) | ||
.then(data => { | ||
if (data.active) { | ||
const iframe = $("#workspace_iframe")[0]; | ||
if (iframe.src !== window.location.origin + data.iframe_src) { | ||
iframe.src = data.iframe_src; | ||
} | ||
} | ||
}); | ||
} | ||
async function fetch_current_module() { | ||
const response = await fetch('/active-module/'); | ||
const data = await response.json(); | ||
|
@@ -20,6 +46,7 @@ async function updateNavbarDropdown() { | |
$("#current #module").val(data.c_current.module_id); | ||
$("#current #challenge").val(data.c_current.challenge_reference_id); | ||
$("#current #challenge-id").val(data.c_current.challenge_id); | ||
$("#dropdown-description").html(data.c_current.description); | ||
|
||
if ("dojo_name" in data.c_previous) { | ||
$("#previous").removeClass("invisible"); | ||
|
@@ -114,13 +141,11 @@ function DropdownStartChallenge(event) { | |
await updateNavbarDropdown(); | ||
$(".challenge-active").removeClass("challenge-active"); | ||
$(`.accordion-item input[value=${params.challenge}]`).closest(".accordion-item").find("h4.challenge-name").addClass("challenge-active"); | ||
if (window.location.href.includes('/workspace/desktop')) { | ||
let iframe_html = await fetch('/workspace/desktop').then(response => response.text()); | ||
let iframe_src = $(iframe_html).find("iframe").attr("src"); | ||
if (iframe_src) { | ||
$("main iframe").attr("src", iframe_src); | ||
} | ||
} | ||
const broadcast_send = new BroadcastChannel('broadcast'); | ||
broadcast_send.postMessage({ | ||
time: new Date().getTime(), | ||
msg: 'New challenge started' | ||
}); | ||
} | ||
else { | ||
let message = "Error:"; | ||
|
@@ -190,6 +215,13 @@ function submitFlag(event) { | |
} | ||
updateNavbarDropdown(); | ||
$(() => { | ||
$("#show_description").click((event) =>{ | ||
$("#dropdown-description").toggle(); | ||
event.stopPropagation(); | ||
}); | ||
$("#dropdown-description").click((event) =>{ | ||
event.stopPropagation(); | ||
}); | ||
$(".close-link").on("click", () => { | ||
$(".navbar") | ||
.addClass("navbar-hiding") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably add a
service = request.args.get("service")
or something like that.