diff options
-rw-r--r-- | planetwars-server/src/db/bots.rs | 6 | ||||
-rw-r--r-- | planetwars-server/src/lib.rs | 1 | ||||
-rw-r--r-- | planetwars-server/src/routes/bots.rs | 17 | ||||
-rw-r--r-- | planetwars-server/src/routes/users.rs | 1 | ||||
-rw-r--r-- | web/pw-server/src/routes/bots/[bot_id].svelte | 34 | ||||
-rw-r--r-- | web/pw-server/src/routes/bots/index.svelte | 71 |
6 files changed, 127 insertions, 3 deletions
diff --git a/planetwars-server/src/db/bots.rs b/planetwars-server/src/db/bots.rs index bc9cb11..d21d9dc 100644 --- a/planetwars-server/src/db/bots.rs +++ b/planetwars-server/src/db/bots.rs @@ -28,6 +28,12 @@ pub fn find_bot(id: i32, conn: &PgConnection) -> QueryResult<Bot> { bots::table.find(id).first(conn) } +pub fn find_bots_by_owner(owner_id: i32, conn: &PgConnection) -> QueryResult<Vec<Bot>> { + bots::table + .filter(bots::owner_id.eq(owner_id)) + .get_results(conn) +} + #[derive(Insertable)] #[table_name = "code_bundles"] pub struct NewCodeBundle<'a> { diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs index 260d668..b3aac5f 100644 --- a/planetwars-server/src/lib.rs +++ b/planetwars-server/src/lib.rs @@ -34,6 +34,7 @@ pub async fn api() -> Router { .route("/login", post(routes::users::login)) .route("/users/me", get(routes::users::current_user)) .route("/bots", post(routes::bots::create_bot)) + .route("/bots/my_bots", get(routes::bots::get_my_bots)) .route("/bots/:bot_id", get(routes::bots::get_bot)) .route("/bots/:bot_id/upload", post(routes::bots::upload_bot_code)) .layer(AddExtensionLayer::new(pool)); diff --git a/planetwars-server/src/routes/bots.rs b/planetwars-server/src/routes/bots.rs index da09669..033c683 100644 --- a/planetwars-server/src/routes/bots.rs +++ b/planetwars-server/src/routes/bots.rs @@ -1,5 +1,6 @@ use axum::extract::{Path, RawBody}; use axum::http::StatusCode; +use axum::response::IntoResponse; use axum::Json; use rand::Rng; use serde::{Deserialize, Serialize}; @@ -30,9 +31,19 @@ pub async fn create_bot( } // TODO: handle errors -pub async fn get_bot(conn: DatabaseConnection, Path(bot_id): Path<i32>) -> Json<Bot> { - let bot = bots::find_bot(bot_id, &conn).unwrap(); - Json(bot) +pub async fn get_bot(conn: DatabaseConnection, Path(bot_id): Path<i32>) -> impl IntoResponse { + bots::find_bot(bot_id, &conn) + .map(Json) + .map_err(|_| StatusCode::NOT_FOUND) +} + +pub async fn get_my_bots( + conn: DatabaseConnection, + user: User, +) -> Result<Json<Vec<Bot>>, StatusCode> { + bots::find_bots_by_owner(user.id, &conn) + .map(Json) + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) } // TODO: proper error handling diff --git a/planetwars-server/src/routes/users.rs b/planetwars-server/src/routes/users.rs index fc77d7b..bc30b28 100644 --- a/planetwars-server/src/routes/users.rs +++ b/planetwars-server/src/routes/users.rs @@ -19,6 +19,7 @@ where async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> { let conn = DatabaseConnection::from_request(req).await?; + let TypedHeader(Authorization(bearer)) = AuthorizationHeader::from_request(req) .await .map_err(|_| (StatusCode::UNAUTHORIZED, "".to_string()))?; diff --git a/web/pw-server/src/routes/bots/[bot_id].svelte b/web/pw-server/src/routes/bots/[bot_id].svelte new file mode 100644 index 0000000..90fd78d --- /dev/null +++ b/web/pw-server/src/routes/bots/[bot_id].svelte @@ -0,0 +1,34 @@ +<script lang="ts" context="module"> + import { get_session_token } from "$lib/auth"; + + export async function load({ page }) { + const token = get_session_token(); + const res = await fetch(`/api/bots/${page.params["bot_id"]}`, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + if (res.ok) { + return { + props: { + bot: await res.json(), + }, + }; + } + + return { + status: res.status, + error: new Error("Could not load bot"), + }; + } +</script> + +<script lang="ts"> + export let bot: object; +</script> + +<div> + {bot["name"]} +</div> diff --git a/web/pw-server/src/routes/bots/index.svelte b/web/pw-server/src/routes/bots/index.svelte new file mode 100644 index 0000000..775652b --- /dev/null +++ b/web/pw-server/src/routes/bots/index.svelte @@ -0,0 +1,71 @@ +<script lang="ts" context="module"> + import { get_session_token } from '$lib/auth'; + + /** @type {import('@sveltejs/kit').Load} */ + export async function load({ params, fetch, session, stuff }) { + const token = get_session_token(); + const res = await fetch('/api/bots/my_bots', { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }); + + if (res.ok) { + return { + props: { + bots: await res.json() + } + }; + } + + return { + status: res.status, + error: new Error('Could not load bots') + }; + } +</script> + +<script lang="ts"> + import { goto } from '$app/navigation'; + + export let bots: object[]; + let name: string | undefined; + + async function createBot() { + const token = get_session_token(); + const res = await fetch('/api/bots', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + name: name + }) + }); + + if (res.ok) { + let bot = await res.json(); + goto(`/bots/${bot['id']}`); + } else { + new Error('creation failed'); + } + } +</script> + +<form on:submit|preventDefault={createBot}> + <label for="name">Name</label> + <input name="name" bind:value={name}/> + <button type="submit">Create</button> +</form> + +<ul> + {#each bots as bot} + <li> + <a target="_blank" href={`bots/${bot['id']}`}> + {bot['name']} + </a> + </li> + {/each} +</ul> |