Added API token handling
+ Tokens can be added by the add_token command or via the CLI + Tokens are checked for authorization before a command is run + Added an error message field to the GeoffreyApiResponse + Made tokens strings instead of u64s + Tokens are randomly generated 64 char long alphanumeric strings + Clippy + Fmtmain
parent
b79db6029e
commit
22ffe75422
|
@ -311,6 +311,7 @@ dependencies = [
|
||||||
"geoffrey_db",
|
"geoffrey_db",
|
||||||
"geoffrey_models",
|
"geoffrey_models",
|
||||||
"log",
|
"log",
|
||||||
|
"rand 0.8.4",
|
||||||
"serde 1.0.124",
|
"serde 1.0.124",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
|
@ -863,9 +864,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha 0.3.0",
|
"rand_chacha 0.3.0",
|
||||||
|
@ -1184,7 +1185,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"rand 0.8.3",
|
"rand 0.8.4",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -1359,7 +1360,7 @@ dependencies = [
|
||||||
"httparse",
|
"httparse",
|
||||||
"input_buffer",
|
"input_buffer",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.3",
|
"rand 0.8.4",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"url",
|
"url",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
|
|
|
@ -17,3 +17,4 @@ config = "0.11.0"
|
||||||
structopt = "0.3.21"
|
structopt = "0.3.21"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
simple_logger = "1.13.0"
|
simple_logger = "1.13.0"
|
||||||
|
rand = "0.8.4"
|
|
@ -0,0 +1,48 @@
|
||||||
|
use crate::commands::{Command, RequestType};
|
||||||
|
use crate::context::Context;
|
||||||
|
use crate::Result;
|
||||||
|
use geoffrey_models::models::parameters::add_token_params::AddTokenParams;
|
||||||
|
use geoffrey_models::models::player::Player;
|
||||||
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
|
use geoffrey_models::models::token::Token;
|
||||||
|
use geoffrey_models::models::CommandLevel;
|
||||||
|
use rand::distributions::Alphanumeric;
|
||||||
|
use rand::Rng;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub struct AddToken {}
|
||||||
|
|
||||||
|
impl Command for AddToken {
|
||||||
|
type Req = AddTokenParams;
|
||||||
|
type Resp = Token;
|
||||||
|
|
||||||
|
fn command_name() -> String {
|
||||||
|
"add_token".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request_type() -> RequestType {
|
||||||
|
RequestType::POST
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_level() -> CommandLevel {
|
||||||
|
CommandLevel::ADMIN
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_command(ctx: Arc<Context>, req: Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
||||||
|
let mut token = Token::default();
|
||||||
|
|
||||||
|
let secret: String = rand::thread_rng()
|
||||||
|
.sample_iter(&Alphanumeric)
|
||||||
|
.take(64)
|
||||||
|
.map(char::from)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
token.secret = secret;
|
||||||
|
|
||||||
|
for permission in req.permissions {
|
||||||
|
token.set_permission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.db.insert(token).map_err(GeoffreyAPIError::from)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,12 +2,13 @@ use crate::commands::add_location::AddLocation;
|
||||||
use crate::commands::find::FindCommand;
|
use crate::commands::find::FindCommand;
|
||||||
use crate::commands::register::Register;
|
use crate::commands::register::Register;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::helper::get_player_from_req;
|
use crate::helper::{get_player_from_req, get_token_from_req};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use geoffrey_models::models::parameters::CommandRequest;
|
use geoffrey_models::models::parameters::CommandRequest;
|
||||||
use geoffrey_models::models::player::Player;
|
use geoffrey_models::models::player::Player;
|
||||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
use geoffrey_models::models::response::APIResponse;
|
use geoffrey_models::models::response::APIResponse;
|
||||||
|
use geoffrey_models::models::token::{Permissions, Token};
|
||||||
use geoffrey_models::models::CommandLevel;
|
use geoffrey_models::models::CommandLevel;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -17,6 +18,7 @@ use warp::filters::BoxedFilter;
|
||||||
use warp::Filter;
|
use warp::Filter;
|
||||||
|
|
||||||
pub mod add_location;
|
pub mod add_location;
|
||||||
|
pub mod add_token;
|
||||||
pub mod find;
|
pub mod find;
|
||||||
pub mod register;
|
pub mod register;
|
||||||
|
|
||||||
|
@ -36,17 +38,29 @@ pub trait Command {
|
||||||
fn command_level() -> CommandLevel;
|
fn command_level() -> CommandLevel;
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp>;
|
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp>;
|
||||||
|
|
||||||
fn user_is_authorized(user: &Option<Player>) -> Result<()> {
|
fn user_is_authorized(token: &Option<Token>, user: &Option<Player>) -> Result<()> {
|
||||||
if Self::command_level() == CommandLevel::ALL {
|
if let Some(token) = token {
|
||||||
Ok(())
|
if !match Self::command_level() {
|
||||||
} else if let Some(user) = user {
|
CommandLevel::MOD => token.check_permission(Permissions::ModCommand),
|
||||||
if user.auth_level >= Self::command_level() {
|
CommandLevel::ADMIN => token.check_permission(Permissions::Admin),
|
||||||
|
_ => token.check_permission(Permissions::Command),
|
||||||
|
} {
|
||||||
|
return Err(GeoffreyAPIError::TokenNotAuthorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
if Self::command_level() == CommandLevel::ALL {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else if let Some(user) = user {
|
||||||
|
if user.auth_level >= Self::command_level() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(GeoffreyAPIError::PermissionInsufficient)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(GeoffreyAPIError::PermissionInsufficient)
|
Err(GeoffreyAPIError::PlayerNotRegistered)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(GeoffreyAPIError::PlayerNotRegistered)
|
Err(GeoffreyAPIError::TokenNotAuthorized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +70,9 @@ pub fn handle_command<T: Command>(ctx: Arc<Context>, req: T::Req) -> Result<T::R
|
||||||
log::debug!("Request: {:?}", req);
|
log::debug!("Request: {:?}", req);
|
||||||
|
|
||||||
let user = get_player_from_req(&ctx.db, &req)?;
|
let user = get_player_from_req(&ctx.db, &req)?;
|
||||||
|
let token = get_token_from_req(&ctx.db, &req)?;
|
||||||
|
|
||||||
match T::user_is_authorized(&user) {
|
match T::user_is_authorized(&token, &user) {
|
||||||
Ok(_) => T::run_command(ctx, req, user),
|
Ok(_) => T::run_command(ctx, req, user),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
@ -75,8 +90,9 @@ pub fn create_command_filter<T: Command>(ctx: Arc<Context>) -> BoxedFilter<(impl
|
||||||
warp::reply::json(&APIResponse::Response::<T::Resp>(reply))
|
warp::reply::json(&APIResponse::Response::<T::Resp>(reply))
|
||||||
} else {
|
} else {
|
||||||
let e = reply.err().unwrap();
|
let e = reply.err().unwrap();
|
||||||
log::warn!("Got error when processing command: {:?}", e);
|
let msg = e.to_string();
|
||||||
warp::reply::json(&APIResponse::<T::Resp>::Error(e))
|
log::warn!("Got error when processing command '{:?}': {}", e, msg);
|
||||||
|
warp::reply::json(&APIResponse::<T::Resp>::Error { error: e, msg })
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::Result;
|
||||||
use geoffrey_db::database::Database;
|
use geoffrey_db::database::Database;
|
||||||
use geoffrey_models::models::parameters::CommandRequest;
|
use geoffrey_models::models::parameters::CommandRequest;
|
||||||
use geoffrey_models::models::player::Player;
|
use geoffrey_models::models::player::Player;
|
||||||
|
use geoffrey_models::models::token::Token;
|
||||||
|
|
||||||
pub fn get_player_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<Option<Player>> {
|
pub fn get_player_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<Option<Player>> {
|
||||||
if let Some(user_id) = req.user_id() {
|
if let Some(user_id) = req.user_id() {
|
||||||
|
@ -12,3 +13,9 @@ pub fn get_player_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_token_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<Option<Token>> {
|
||||||
|
Ok(db
|
||||||
|
.filter(|_, token: &Token| token.secret == req.token())?
|
||||||
|
.next())
|
||||||
|
}
|
||||||
|
|
|
@ -4,14 +4,19 @@ mod context;
|
||||||
mod helper;
|
mod helper;
|
||||||
mod logging;
|
mod logging;
|
||||||
|
|
||||||
use crate::commands::command_filter;
|
use crate::commands::add_token::AddToken;
|
||||||
|
use crate::commands::{command_filter, Command};
|
||||||
use crate::config::GeoffreyAPIConfig;
|
use crate::config::GeoffreyAPIConfig;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::logging::{init_logging, LogLevel};
|
use crate::logging::{init_logging, LogLevel};
|
||||||
|
use geoffrey_models::models::parameters::add_token_params::AddTokenParams;
|
||||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
|
use geoffrey_models::models::token::Permissions;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
|
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
|
||||||
|
@ -29,6 +34,54 @@ struct Args {
|
||||||
default_value = "Info"
|
default_value = "Info"
|
||||||
)]
|
)]
|
||||||
log_level: LogLevel,
|
log_level: LogLevel,
|
||||||
|
|
||||||
|
#[structopt(subcommand)]
|
||||||
|
command: GeoffreyApiCommand,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, StructOpt, Clone)]
|
||||||
|
enum GeoffreyApiCommand {
|
||||||
|
Run,
|
||||||
|
CreateAdminToken(CreateTokenCommand),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt, PartialEq, Clone)]
|
||||||
|
struct CreateTokenCommand {
|
||||||
|
#[structopt(parse(try_from_str = Permissions::try_from))]
|
||||||
|
pub permissions: Vec<Permissions>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_server(ctx: Arc<Context>) {
|
||||||
|
let socket_addr = match SocketAddr::from_str(ctx.cfg.host.as_str()) {
|
||||||
|
Ok(socket_addr) => socket_addr,
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Error parsing {} as address: {}", ctx.cfg.host, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let api = command_filter(ctx.clone());
|
||||||
|
|
||||||
|
warp::serve(api).run(socket_addr).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_token(ctx: Arc<Context>, perms: Vec<Permissions>) {
|
||||||
|
match AddToken::run_command(
|
||||||
|
ctx,
|
||||||
|
AddTokenParams {
|
||||||
|
token: "".to_string(),
|
||||||
|
permissions: perms,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
) {
|
||||||
|
Ok(token) => {
|
||||||
|
// Don't log this to keep tokens out of the log
|
||||||
|
println!("Added admin token with secret: {}", token.secret)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Unable to create admin token: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -48,17 +101,10 @@ async fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let socket_addr = match SocketAddr::from_str(cfg.host.as_str()) {
|
|
||||||
Ok(socket_addr) => socket_addr,
|
|
||||||
Err(e) => {
|
|
||||||
log::warn!("Error parsing {} as address: {}", cfg.host, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ctx = Context::new(cfg).unwrap();
|
let ctx = Context::new(cfg).unwrap();
|
||||||
|
|
||||||
let api = command_filter(ctx.clone());
|
match args.command {
|
||||||
|
GeoffreyApiCommand::Run => run_server(ctx).await,
|
||||||
warp::serve(api).run(socket_addr).await;
|
GeoffreyApiCommand::CreateAdminToken(perms) => create_token(ctx, perms.permissions),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,5 +52,6 @@ pub struct Tunnel {
|
||||||
pub enum CommandLevel {
|
pub enum CommandLevel {
|
||||||
ALL = 0,
|
ALL = 0,
|
||||||
REGISTERED = 1,
|
REGISTERED = 1,
|
||||||
ADMIN = 2,
|
MOD = 2,
|
||||||
|
ADMIN = 3,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct AddLocationParams {
|
pub struct AddLocationParams {
|
||||||
token: u64,
|
pub token: String,
|
||||||
user_id: UserID,
|
pub user_id: UserID,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub position: Position,
|
pub position: Position,
|
||||||
pub loc_type: LocationType,
|
pub loc_type: LocationType,
|
||||||
|
@ -15,8 +15,8 @@ pub struct AddLocationParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for AddLocationParams {
|
impl CommandRequest for AddLocationParams {
|
||||||
fn token(&self) -> u64 {
|
fn token(&self) -> String {
|
||||||
self.token
|
self.token.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
fn user_id(&self) -> Option<UserID> {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
use crate::models::parameters::CommandRequest;
|
||||||
|
use crate::models::player::UserID;
|
||||||
|
use crate::models::token::Permissions;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct AddTokenParams {
|
||||||
|
pub token: String,
|
||||||
|
pub permissions: Vec<Permissions>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandRequest for AddTokenParams {
|
||||||
|
fn token(&self) -> String {
|
||||||
|
self.token.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_id(&self) -> Option<UserID> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,12 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct FindParams {
|
pub struct FindParams {
|
||||||
pub token: u64,
|
pub token: String,
|
||||||
pub query: String,
|
pub query: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for FindParams {
|
impl CommandRequest for FindParams {
|
||||||
fn token(&self) -> u64 {
|
fn token(&self) -> String {
|
||||||
self.token
|
self.token.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod add_location_params;
|
pub mod add_location_params;
|
||||||
|
pub mod add_token_params;
|
||||||
pub mod find_params;
|
pub mod find_params;
|
||||||
pub mod register_params;
|
pub mod register_params;
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ use serde::Serialize;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait CommandRequest: Serialize + DeserializeOwned + Debug + Clone + Send + 'static {
|
pub trait CommandRequest: Serialize + DeserializeOwned + Debug + Clone + Send + 'static {
|
||||||
fn token(&self) -> u64;
|
fn token(&self) -> String;
|
||||||
fn user_id(&self) -> Option<UserID> {
|
fn user_id(&self) -> Option<UserID> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct RegisterParameters {
|
pub struct RegisterParameters {
|
||||||
pub token: u64,
|
pub token: String,
|
||||||
pub new_user_id: UserID,
|
pub new_user_id: UserID,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for RegisterParameters {
|
impl CommandRequest for RegisterParameters {
|
||||||
fn token(&self) -> u64 {
|
fn token(&self) -> String {
|
||||||
self.token
|
self.token.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,32 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub enum GeoffreyAPIError {
|
pub enum GeoffreyAPIError {
|
||||||
PlayerNotRegistered,
|
PlayerNotRegistered,
|
||||||
EntryNotFound,
|
EntryNotFound,
|
||||||
PermissionInsufficient,
|
PermissionInsufficient,
|
||||||
EntryNotUnique,
|
EntryNotUnique,
|
||||||
DatabaseError(String),
|
DatabaseError(String),
|
||||||
|
TokenNotAuthorized,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for GeoffreyAPIError {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let string = match self {
|
||||||
|
GeoffreyAPIError::PlayerNotRegistered => "Player has not been registered.".to_string(),
|
||||||
|
GeoffreyAPIError::EntryNotFound => {
|
||||||
|
"An entry that matches that query was not found.".to_string()
|
||||||
|
}
|
||||||
|
GeoffreyAPIError::PermissionInsufficient => {
|
||||||
|
"Insufficient permission to preform that action".to_string()
|
||||||
|
}
|
||||||
|
GeoffreyAPIError::EntryNotUnique => "Entry not unique in the DB.".to_string(),
|
||||||
|
GeoffreyAPIError::DatabaseError(e) => format!("Database Error: {}", e),
|
||||||
|
GeoffreyAPIError::TokenNotAuthorized => {
|
||||||
|
"Token supplied in request is not authorized".to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
write!(f, "{}", string)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,8 @@ pub mod api_error;
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum APIResponse<T> {
|
pub enum APIResponse<T> {
|
||||||
Response(T),
|
Response(T),
|
||||||
Error(GeoffreyAPIError),
|
Error {
|
||||||
|
error: GeoffreyAPIError,
|
||||||
|
msg: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::GeoffreyDatabaseModel;
|
use crate::GeoffreyDatabaseModel;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, PartialEq)]
|
||||||
pub enum Permissions {
|
pub enum Permissions {
|
||||||
ModelGet = 0,
|
ModelGet = 0,
|
||||||
ModelPost,
|
ModelPost,
|
||||||
|
@ -10,12 +12,27 @@ pub enum Permissions {
|
||||||
Admin,
|
Admin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for Permissions {
|
||||||
|
type Error = String;
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
Ok(match s {
|
||||||
|
"ModelGet" => Self::ModelGet,
|
||||||
|
"ModelPost" => Self::ModelPost,
|
||||||
|
"Command" => Self::Command,
|
||||||
|
"ModCommand" => Self::ModCommand,
|
||||||
|
"Admin" => Self::Admin,
|
||||||
|
_ => return Err(format!("Unable to parse '{}' as a permission", s)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Token {
|
pub struct Token {
|
||||||
pub id: Option<u64>,
|
pub id: Option<u64>,
|
||||||
permission: u64,
|
permission: u64,
|
||||||
pub created: DateTime<Utc>,
|
pub created: DateTime<Utc>,
|
||||||
pub modified: DateTime<Utc>,
|
pub modified: DateTime<Utc>,
|
||||||
|
pub secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token {
|
impl Token {
|
||||||
|
@ -43,6 +60,7 @@ impl Default for Token {
|
||||||
permission: 0,
|
permission: 0,
|
||||||
created: Utc::now(),
|
created: Utc::now(),
|
||||||
modified: Utc::now(),
|
modified: Utc::now(),
|
||||||
|
secret: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue