Compare commits

..

No commits in common. "0b25e3fb87ce5591b557a2506da65e14eef67c02" and "725a16d1f5fe5f767bbe76eef91c8bee8d17a492" have entirely different histories.

5 changed files with 6 additions and 103 deletions

View file

@ -1,7 +1,7 @@
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use actix_web::{error, post, web, Error, HttpResponse}; use actix_web::{error, post, web, Error, HttpResponse};
use argon2::{PasswordHash, PasswordVerifier}; use argon2::{Argon2, PasswordHash, PasswordVerifier};
use regex::Regex; use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use futures::StreamExt; use futures::StreamExt;

View file

@ -1,8 +1,4 @@
use std::{str::FromStr, time::{SystemTime, UNIX_EPOCH}}; use actix_web::{Scope, web};
use actix_web::{web, HttpResponse, Scope};
use sqlx::Postgres;
use uuid::Uuid;
mod register; mod register;
mod login; mod login;
@ -14,28 +10,3 @@ pub fn web() -> Scope {
.service(login::response) .service(login::response)
.service(refresh::res) .service(refresh::res)
} }
pub async fn check_access_token(access_token: String, pool: sqlx::Pool<Postgres>) -> Result<Uuid, HttpResponse> {
match sqlx::query_as("SELECT CAST(uuid as VARCHAR), created FROM access_tokens WHERE token = $1")
.bind(&access_token)
.fetch_one(&pool)
.await {
Ok(row) => {
let (uuid, created): (String, i64) = row;
let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i64;
let lifetime = current_time - created;
if lifetime > 3600 {
return Err(HttpResponse::Unauthorized().finish())
}
Ok(Uuid::from_str(&uuid).unwrap())
},
Err(error) => {
eprintln!("{}", error);
Err(HttpResponse::InternalServerError().finish())
}
}
}

View file

@ -2,11 +2,9 @@ use actix_web::{Scope, web};
mod stats; mod stats;
mod auth; mod auth;
mod user;
pub fn web() -> Scope { pub fn web() -> Scope {
web::scope("/v1") web::scope("/v1")
.service(stats::res) .service(stats::res)
.service(auth::web()) .service(auth::web())
.service(user::res)
} }

View file

@ -1,66 +0,0 @@
use actix_web::{error, post, web, Error, HttpResponse};
use serde::{Deserialize, Serialize};
use futures::StreamExt;
use crate::{api::v1::auth::check_access_token, Data};
#[derive(Deserialize)]
struct AuthenticationRequest {
access_token: String,
}
#[derive(Serialize)]
struct Response {
uuid: String,
username: String,
display_name: String,
}
const MAX_SIZE: usize = 262_144;
#[post("/user/{uuid}")]
pub async fn res(mut payload: web::Payload, path: web::Path<(String,)>, data: web::Data<Data>) -> Result<HttpResponse, Error> {
let mut body = web::BytesMut::new();
while let Some(chunk) = payload.next().await {
let chunk = chunk?;
// limit max size of in-memory payload
if (body.len() + chunk.len()) > MAX_SIZE {
return Err(error::ErrorBadRequest("overflow"));
}
body.extend_from_slice(&chunk);
}
let request = path.into_inner().0;
let authentication_request = serde_json::from_slice::<AuthenticationRequest>(&body)?;
let authorized = check_access_token(authentication_request.access_token, data.pool.clone()).await;
if authorized.is_err() {
return Ok(authorized.unwrap_err())
}
let uuid = authorized.unwrap();
if request == "me" {
let row = sqlx::query_as(&format!("SELECT username, display_name FROM users WHERE uuid = '{}'", uuid))
.fetch_one(&data.pool)
.await
.unwrap();
let (username, display_name): (String, Option<String>) = row;
return Ok(HttpResponse::Ok().json(Response { uuid: uuid.to_string(), username, display_name: display_name.unwrap_or_default() }))
} else {
println!("{}", request);
if let Ok(row) = sqlx::query_as(&format!("SELECT CAST(uuid as VARCHAR), username, display_name FROM users WHERE uuid = '{}'", request))
.fetch_one(&data.pool)
.await {
let (uuid, username, display_name): (String, String, Option<String>) = row;
return Ok(HttpResponse::Ok().json(Response { uuid, username, display_name: display_name.unwrap_or_default() }))
}
Ok(HttpResponse::NotFound().finish())
}
}

View file

@ -50,18 +50,18 @@ async fn main() -> Result<(), Error> {
email_verified boolean NOT NULL DEFAULT FALSE email_verified boolean NOT NULL DEFAULT FALSE
); );
CREATE TABLE IF NOT EXISTS instance_permissions ( CREATE TABLE IF NOT EXISTS instance_permissions (
uuid uuid NOT NULL REFERENCES users(uuid), uuid uuid REFERENCES users(uuid),
administrator boolean NOT NULL DEFAULT FALSE administrator boolean NOT NULL DEFAULT FALSE
); );
CREATE TABLE IF NOT EXISTS refresh_tokens ( CREATE TABLE IF NOT EXISTS refresh_tokens (
token varchar(64) PRIMARY KEY UNIQUE NOT NULL, token varchar(64) PRIMARY KEY UNIQUE NOT NULL,
uuid uuid NOT NULL REFERENCES users(uuid), uuid uuid REFERENCES users(uuid),
created int8 NOT NULL created int8 NOT NULL
); );
CREATE TABLE IF NOT EXISTS access_tokens ( CREATE TABLE IF NOT EXISTS access_tokens (
token varchar(32) PRIMARY KEY UNIQUE NOT NULL, token varchar(32) PRIMARY KEY UNIQUE NOT NULL,
refresh_token varchar(64) UNIQUE NOT NULL REFERENCES refresh_tokens(token), refresh_token varchar(64) UNIQUE REFERENCES refresh_tokens(token),
uuid uuid NOT NULL REFERENCES users(uuid), uuid uuid REFERENCES users(uuid),
created int8 NOT NULL created int8 NOT NULL
) )
"#) "#)