Configured Rustfmt
parent
b13b760e2f
commit
16ddc9aecd
|
@ -0,0 +1,69 @@
|
||||||
|
binop_separator = "Front"
|
||||||
|
blank_lines_lower_bound = 0
|
||||||
|
blank_lines_upper_bound = 1
|
||||||
|
# Trying something new
|
||||||
|
brace_style = "AlwaysNextLine"
|
||||||
|
color = "Auto"
|
||||||
|
combine_control_expr = false
|
||||||
|
comment_width = 80
|
||||||
|
condense_wildcard_suffixes = false
|
||||||
|
control_brace_style = "AlwaysSameLine"
|
||||||
|
disable_all_formatting = false
|
||||||
|
edition = "2018"
|
||||||
|
emit_mode = "Files"
|
||||||
|
empty_item_single_line = true
|
||||||
|
enum_discrim_align_threshold = 0
|
||||||
|
error_on_line_overflow = false
|
||||||
|
error_on_unformatted = false
|
||||||
|
fn_args_layout = "Tall"
|
||||||
|
fn_single_line = false
|
||||||
|
force_explicit_abi = true
|
||||||
|
force_multiline_blocks = false
|
||||||
|
format_code_in_doc_comments = false
|
||||||
|
format_macro_bodies = true
|
||||||
|
format_macro_matchers = false
|
||||||
|
format_strings = false
|
||||||
|
group_imports = "StdExternalCrate"
|
||||||
|
hard_tabs = false
|
||||||
|
hide_parse_errors = false
|
||||||
|
ignore = []
|
||||||
|
imports_granularity = "Crate"
|
||||||
|
imports_indent = "Block"
|
||||||
|
imports_layout = "Mixed"
|
||||||
|
indent_style = "Block"
|
||||||
|
inline_attribute_width = 0
|
||||||
|
license_template_path = ""
|
||||||
|
make_backup = false
|
||||||
|
match_arm_blocks = true
|
||||||
|
match_arm_leading_pipes = "Never"
|
||||||
|
match_block_trailing_comma = false
|
||||||
|
max_width = 100
|
||||||
|
merge_derives = true
|
||||||
|
newline_style = "Auto"
|
||||||
|
normalize_comments = false
|
||||||
|
normalize_doc_attributes = false
|
||||||
|
overflow_delimited_expr = false
|
||||||
|
remove_nested_parens = true
|
||||||
|
reorder_impl_items = false
|
||||||
|
reorder_imports = true
|
||||||
|
reorder_modules = true
|
||||||
|
report_fixme = "Always"
|
||||||
|
report_todo = "Always"
|
||||||
|
required_version = "1.4.36"
|
||||||
|
skip_children = false
|
||||||
|
space_after_colon = true
|
||||||
|
space_before_colon = false
|
||||||
|
spaces_around_ranges = false
|
||||||
|
struct_field_align_threshold = 0
|
||||||
|
struct_lit_single_line = true
|
||||||
|
tab_spaces = 4
|
||||||
|
trailing_comma = "Vertical"
|
||||||
|
trailing_semicolon = true
|
||||||
|
type_punctuation_density = "Wide"
|
||||||
|
unstable_features = false
|
||||||
|
use_field_init_shorthand = false
|
||||||
|
use_small_heuristics = "Default"
|
||||||
|
use_try_shorthand = false
|
||||||
|
version = "One"
|
||||||
|
where_single_line = false
|
||||||
|
wrap_comments = false
|
45
src/auth.rs
45
src/auth.rs
|
@ -1,21 +1,23 @@
|
||||||
use crate::errors::RBError;
|
|
||||||
use crate::db::{
|
|
||||||
users::{User, NewUser},
|
|
||||||
tokens::{RefreshToken, NewRefreshToken}
|
|
||||||
};
|
|
||||||
use crate::schema::refresh_tokens::dsl as refresh_tokens;
|
|
||||||
use crate::schema::users::dsl as users;
|
|
||||||
use argon2::verify_encoded;
|
use argon2::verify_encoded;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use diesel::prelude::*;
|
use diesel::{insert_into, prelude::*, PgConnection};
|
||||||
use diesel::{insert_into, PgConnection};
|
|
||||||
use hmac::{Hmac, NewMac};
|
use hmac::{Hmac, NewMac};
|
||||||
use jwt::SignWithKey;
|
use jwt::SignWithKey;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> crate::Result<User> {
|
use crate::{
|
||||||
|
db::{
|
||||||
|
tokens::{NewRefreshToken, RefreshToken},
|
||||||
|
users::{NewUser, User},
|
||||||
|
},
|
||||||
|
errors::RBError,
|
||||||
|
schema::{refresh_tokens::dsl as refresh_tokens, users::dsl as users},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> crate::Result<User>
|
||||||
|
{
|
||||||
// TODO handle non-"NotFound" Diesel errors accordingely
|
// TODO handle non-"NotFound" Diesel errors accordingely
|
||||||
let user = users::users
|
let user = users::users
|
||||||
.filter(users::username.eq(username))
|
.filter(users::username.eq(username))
|
||||||
|
@ -35,20 +37,23 @@ pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> crate
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct JWTResponse {
|
pub struct JWTResponse
|
||||||
|
{
|
||||||
token: String,
|
token: String,
|
||||||
refresh_token: String,
|
refresh_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Claims {
|
pub struct Claims
|
||||||
|
{
|
||||||
pub id: uuid::Uuid,
|
pub id: uuid::Uuid,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
pub exp: i64,
|
pub exp: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_jwt_token(conn: &PgConnection, user: &User) -> crate::Result<JWTResponse> {
|
pub fn generate_jwt_token(conn: &PgConnection, user: &User) -> crate::Result<JWTResponse>
|
||||||
|
{
|
||||||
let secret = std::env::var("JWT_KEY").map_err(|_| RBError::MissingJWTKey)?;
|
let secret = std::env::var("JWT_KEY").map_err(|_| RBError::MissingJWTKey)?;
|
||||||
let key: Hmac<Sha256> =
|
let key: Hmac<Sha256> =
|
||||||
Hmac::new_from_slice(secret.as_bytes()).map_err(|_| RBError::JWTCreationError)?;
|
Hmac::new_from_slice(secret.as_bytes()).map_err(|_| RBError::JWTCreationError)?;
|
||||||
|
@ -92,7 +97,8 @@ pub fn generate_jwt_token(conn: &PgConnection, user: &User) -> crate::Result<JWT
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_password(password: &str) -> crate::Result<String> {
|
pub fn hash_password(password: &str) -> crate::Result<String>
|
||||||
|
{
|
||||||
// Generate a random salt
|
// Generate a random salt
|
||||||
let mut salt = [0u8; 64];
|
let mut salt = [0u8; 64];
|
||||||
thread_rng().fill(&mut salt[..]);
|
thread_rng().fill(&mut salt[..]);
|
||||||
|
@ -102,11 +108,9 @@ pub fn hash_password(password: &str) -> crate::Result<String> {
|
||||||
argon2::hash_encoded(password.as_bytes(), &salt, &config).map_err(|_| RBError::PWSaltError)
|
argon2::hash_encoded(password.as_bytes(), &salt, &config).map_err(|_| RBError::PWSaltError)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_admin_user(
|
pub fn create_admin_user(conn: &PgConnection, username: &str, password: &str)
|
||||||
conn: &PgConnection,
|
-> crate::Result<bool>
|
||||||
username: &str,
|
{
|
||||||
password: &str,
|
|
||||||
) -> crate::Result<bool> {
|
|
||||||
let pass_hashed = hash_password(password)?;
|
let pass_hashed = hash_password(password)?;
|
||||||
let new_user = NewUser {
|
let new_user = NewUser {
|
||||||
username: username.to_string(),
|
username: username.to_string(),
|
||||||
|
@ -125,7 +129,8 @@ pub fn create_admin_user(
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refresh_token(conn: &PgConnection, refresh_token: &str) -> crate::Result<JWTResponse> {
|
pub fn refresh_token(conn: &PgConnection, refresh_token: &str) -> crate::Result<JWTResponse>
|
||||||
|
{
|
||||||
let token_bytes = base64::decode(refresh_token).map_err(|_| RBError::InvalidRefreshToken)?;
|
let token_bytes = base64::decode(refresh_token).map_err(|_| RBError::InvalidRefreshToken)?;
|
||||||
|
|
||||||
// First, we request the token from the database to see if it's really a valid token
|
// First, we request the token from the database to see if it's really a valid token
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod users;
|
|
||||||
pub mod tokens;
|
pub mod tokens;
|
||||||
|
pub mod users;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
use diesel::{Insertable, Queryable};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use diesel::{Queryable, Insertable};
|
|
||||||
use crate::schema::refresh_tokens;
|
use crate::schema::refresh_tokens;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Queryable)]
|
#[derive(Queryable)]
|
||||||
pub struct RefreshToken {
|
pub struct RefreshToken
|
||||||
|
{
|
||||||
pub token: Vec<u8>,
|
pub token: Vec<u8>,
|
||||||
pub user_id: Uuid,
|
pub user_id: Uuid,
|
||||||
pub expires_at: chrono::NaiveDateTime,
|
pub expires_at: chrono::NaiveDateTime,
|
||||||
|
@ -13,7 +14,8 @@ pub struct RefreshToken {
|
||||||
|
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable)]
|
||||||
#[table_name = "refresh_tokens"]
|
#[table_name = "refresh_tokens"]
|
||||||
pub struct NewRefreshToken {
|
pub struct NewRefreshToken
|
||||||
|
{
|
||||||
pub token: Vec<u8>,
|
pub token: Vec<u8>,
|
||||||
pub user_id: Uuid,
|
pub user_id: Uuid,
|
||||||
pub expires_at: chrono::NaiveDateTime,
|
pub expires_at: chrono::NaiveDateTime,
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
use crate::schema::users;
|
use diesel::{prelude::*, AsChangeset, Insertable, Queryable};
|
||||||
use diesel::{AsChangeset, Insertable, Queryable, prelude::*};
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::schema::users::dsl::*;
|
|
||||||
use crate::errors::RBError;
|
use crate::{
|
||||||
|
errors::RBError,
|
||||||
|
schema::{users, users::dsl::*},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Queryable, Serialize)]
|
#[derive(Queryable, Serialize)]
|
||||||
pub struct User {
|
pub struct User
|
||||||
|
{
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
|
@ -18,12 +21,14 @@ pub struct User {
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset)]
|
#[derive(Insertable, AsChangeset)]
|
||||||
#[table_name = "users"]
|
#[table_name = "users"]
|
||||||
pub struct NewUser {
|
pub struct NewUser
|
||||||
|
{
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub admin: bool,
|
pub admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all(conn: &PgConnection) -> crate::Result<Vec<User>> {
|
pub fn all(conn: &PgConnection) -> crate::Result<Vec<User>>
|
||||||
|
{
|
||||||
users.load::<User>(conn).map_err(|_| RBError::DBError)
|
users.load::<User>(conn).map_err(|_| RBError::DBError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
use rocket::http::Status;
|
|
||||||
use rocket::request::Request;
|
|
||||||
use rocket::response::{self, Responder, Response};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use rocket::{
|
||||||
|
http::Status,
|
||||||
|
request::Request,
|
||||||
|
response::{self, Responder, Response},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RBError {
|
pub enum RBError
|
||||||
|
{
|
||||||
/// When the login requests an unknown user
|
/// When the login requests an unknown user
|
||||||
UnknownUser,
|
UnknownUser,
|
||||||
BlockedUser,
|
BlockedUser,
|
||||||
|
@ -26,8 +30,10 @@ pub enum RBError {
|
||||||
DBError,
|
DBError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r> Responder<'r, 'static> for RBError {
|
impl<'r> Responder<'r, 'static> for RBError
|
||||||
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {
|
{
|
||||||
|
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static>
|
||||||
|
{
|
||||||
let (status, message): (Status, &str) = match self {
|
let (status, message): (Status, &str) = match self {
|
||||||
RBError::UnknownUser => (Status::NotFound, "Unknown user"),
|
RBError::UnknownUser => (Status::NotFound, "Unknown user"),
|
||||||
RBError::BlockedUser => (Status::Unauthorized, "This user is blocked"),
|
RBError::BlockedUser => (Status::Unauthorized, "This user is blocked"),
|
||||||
|
|
|
@ -12,10 +12,12 @@ use sha2::Sha256;
|
||||||
pub struct Bearer(String);
|
pub struct Bearer(String);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for Bearer {
|
impl<'r> FromRequest<'r> for Bearer
|
||||||
|
{
|
||||||
type Error = rb::errors::RBError;
|
type Error = rb::errors::RBError;
|
||||||
|
|
||||||
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error>
|
||||||
|
{
|
||||||
// If the header isn't present, just forward to the next route
|
// If the header isn't present, just forward to the next route
|
||||||
let header = match req.headers().get_one("Authorization") {
|
let header = match req.headers().get_one("Authorization") {
|
||||||
None => return Outcome::Forward(()),
|
None => return Outcome::Forward(()),
|
||||||
|
@ -40,10 +42,12 @@ impl<'r> FromRequest<'r> for Bearer {
|
||||||
pub struct JWT(Claims);
|
pub struct JWT(Claims);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for JWT {
|
impl<'r> FromRequest<'r> for JWT
|
||||||
|
{
|
||||||
type Error = rb::errors::RBError;
|
type Error = rb::errors::RBError;
|
||||||
|
|
||||||
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error>
|
||||||
|
{
|
||||||
let bearer = try_outcome!(req.guard::<Bearer>().await).0;
|
let bearer = try_outcome!(req.guard::<Bearer>().await).0;
|
||||||
|
|
||||||
// Get secret & key
|
// Get secret & key
|
||||||
|
@ -73,10 +77,12 @@ impl<'r> FromRequest<'r> for JWT {
|
||||||
pub struct User(Claims);
|
pub struct User(Claims);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for User {
|
impl<'r> FromRequest<'r> for User
|
||||||
|
{
|
||||||
type Error = rb::errors::RBError;
|
type Error = rb::errors::RBError;
|
||||||
|
|
||||||
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error>
|
||||||
|
{
|
||||||
let claims = try_outcome!(req.guard::<JWT>().await).0;
|
let claims = try_outcome!(req.guard::<JWT>().await).0;
|
||||||
|
|
||||||
// Verify key hasn't yet expired
|
// Verify key hasn't yet expired
|
||||||
|
@ -92,10 +98,12 @@ impl<'r> FromRequest<'r> for User {
|
||||||
pub struct Admin(Claims);
|
pub struct Admin(Claims);
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
impl<'r> FromRequest<'r> for Admin {
|
impl<'r> FromRequest<'r> for Admin
|
||||||
|
{
|
||||||
type Error = rb::errors::RBError;
|
type Error = rb::errors::RBError;
|
||||||
|
|
||||||
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error>
|
||||||
|
{
|
||||||
let user = try_outcome!(req.guard::<User>().await);
|
let user = try_outcome!(req.guard::<User>().await);
|
||||||
if user.0.admin {
|
if user.0.admin {
|
||||||
Outcome::Success(Self(user.0))
|
Outcome::Success(Self(user.0))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
|
||||||
pub mod db;
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
|
pub mod db;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub(crate) mod schema;
|
pub(crate) mod schema;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ embed_migrations!();
|
||||||
#[database("postgres_rb")]
|
#[database("postgres_rb")]
|
||||||
pub struct RbDbConn(diesel::PgConnection);
|
pub struct RbDbConn(diesel::PgConnection);
|
||||||
|
|
||||||
async fn run_db_migrations(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocket<Build>> {
|
async fn run_db_migrations(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocket<Build>>
|
||||||
|
{
|
||||||
let conn = RbDbConn::get_one(&rocket)
|
let conn = RbDbConn::get_one(&rocket)
|
||||||
.await
|
.await
|
||||||
.expect("database connection");
|
.expect("database connection");
|
||||||
|
@ -29,7 +30,8 @@ async fn run_db_migrations(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocke
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_admin_user(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocket<Build>> {
|
async fn create_admin_user(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocket<Build>>
|
||||||
|
{
|
||||||
let admin_user = std::env::var("ADMIN_USER").unwrap_or(String::from("admin"));
|
let admin_user = std::env::var("ADMIN_USER").unwrap_or(String::from("admin"));
|
||||||
let admin_password = std::env::var("ADMIN_PASSWORD").unwrap_or(String::from("password"));
|
let admin_password = std::env::var("ADMIN_PASSWORD").unwrap_or(String::from("password"));
|
||||||
|
|
||||||
|
@ -46,7 +48,8 @@ async fn create_admin_user(rocket: Rocket<Build>) -> Result<Rocket<Build>, Rocke
|
||||||
}
|
}
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
fn rocket() -> _ {
|
fn rocket() -> _
|
||||||
|
{
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.attach(RbDbConn::fairing())
|
.attach(RbDbConn::fairing())
|
||||||
.attach(AdHoc::try_on_ignite(
|
.attach(AdHoc::try_on_ignite(
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
use crate::guards::Admin;
|
|
||||||
use crate::RbDbConn;
|
|
||||||
use rb::db::users::User;
|
use rb::db::users::User;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
pub fn routes() -> Vec<rocket::Route> {
|
use crate::{guards::Admin, RbDbConn};
|
||||||
|
|
||||||
|
pub fn routes() -> Vec<rocket::Route>
|
||||||
|
{
|
||||||
routes![get_users]
|
routes![get_users]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/users")]
|
#[get("/users")]
|
||||||
async fn get_users(admin: Admin, conn: RbDbConn) -> rb::Result<Json<Vec<User>>> {
|
async fn get_users(admin: Admin, conn: RbDbConn) -> rb::Result<Json<Vec<User>>>
|
||||||
|
{
|
||||||
Ok(Json(conn.run(|c| rb::db::users::all(c)).await?))
|
Ok(Json(conn.run(|c| rb::db::users::all(c)).await?))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
use crate::guards::User;
|
|
||||||
use crate::RbDbConn;
|
|
||||||
use rb::auth::{generate_jwt_token, verify_user, JWTResponse};
|
use rb::auth::{generate_jwt_token, verify_user, JWTResponse};
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub(crate) fn routes() -> Vec<rocket::Route> {
|
use crate::{guards::User, RbDbConn};
|
||||||
|
|
||||||
|
pub(crate) fn routes() -> Vec<rocket::Route>
|
||||||
|
{
|
||||||
routes![login, already_logged_in, refresh_token]
|
routes![login, already_logged_in, refresh_token]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Credentials {
|
struct Credentials
|
||||||
|
{
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/login")]
|
#[post("/login")]
|
||||||
async fn already_logged_in(_user: User) -> String {
|
async fn already_logged_in(_user: User) -> String
|
||||||
|
{
|
||||||
String::from("You're already logged in!")
|
String::from("You're already logged in!")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/login", data = "<credentials>", rank = 2)]
|
#[post("/login", data = "<credentials>", rank = 2)]
|
||||||
async fn login(conn: RbDbConn, credentials: Json<Credentials>) -> rb::Result<Json<JWTResponse>> {
|
async fn login(conn: RbDbConn, credentials: Json<Credentials>) -> rb::Result<Json<JWTResponse>>
|
||||||
|
{
|
||||||
let credentials = credentials.into_inner();
|
let credentials = credentials.into_inner();
|
||||||
|
|
||||||
// Get the user, if credentials are valid
|
// Get the user, if credentials are valid
|
||||||
|
@ -33,7 +37,8 @@ async fn login(conn: RbDbConn, credentials: Json<Credentials>) -> rb::Result<Jso
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct RefreshTokenRequest {
|
struct RefreshTokenRequest
|
||||||
|
{
|
||||||
pub refresh_token: String,
|
pub refresh_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +46,8 @@ struct RefreshTokenRequest {
|
||||||
async fn refresh_token(
|
async fn refresh_token(
|
||||||
conn: RbDbConn,
|
conn: RbDbConn,
|
||||||
refresh_token_request: Json<RefreshTokenRequest>,
|
refresh_token_request: Json<RefreshTokenRequest>,
|
||||||
) -> rb::Result<Json<JWTResponse>> {
|
) -> rb::Result<Json<JWTResponse>>
|
||||||
|
{
|
||||||
let refresh_token = refresh_token_request.into_inner().refresh_token;
|
let refresh_token = refresh_token_request.into_inner().refresh_token;
|
||||||
|
|
||||||
Ok(Json(
|
Ok(Json(
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod auth;
|
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
|
pub mod auth;
|
||||||
|
|
Reference in New Issue