Skip to content
This repository was archived by the owner on Jan 8, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ rocket = { version = "0.5.0-rc.1", features = [
] }
serde = "1.0.133"

[dependencies.uuid]
version = "1.1.2"
features = [
"v4", # Lets you generate random UUIDs
"fast-rng", # Use a faster (but still sufficiently random) RNG
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
]

[dependencies.sea-orm]
version = "^0.5.0"
features = ["macros", "runtime-tokio-native-tls"]
Expand Down
13 changes: 10 additions & 3 deletions src/auth/auth_preflag_request_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,28 @@ impl<'r> FromRequest<'r> for AuthPreflag {
.get(0)
{
Some(key) => key.to_string(),
None => return Outcome::Failure((Status::BadRequest, AuthError::Missing)),

// 401 Unauthorized is sent due to that status code being used to signify you don't have authorization in your request
// None => return Outcome::Failure((Status::BadRequest, AuthError::Missing)),
None => return Outcome::Failure((Status::Unauthorized, AuthError::Missing)),
};

let db = match req.guard::<Connection<'_, Db>>().await {
Success(db) => db.into_inner(),

// 403 Forbidden is sent due to that status code being used to signify you don't have permission
// _ => return Outcome::Failure((Status::BadRequest, AuthError::Invalid)),
_ => return Outcome::Failure((Status::BadRequest, AuthError::Invalid)),
};

match match crate::db_get::api_keys::api_key_exists(db, &api_key).await {
Ok(exists) => exists,
Err(e) => {
// 500 Internal Server Error is sent because of a database error
return Outcome::Failure((
Status::BadRequest,
Status::InternalServerError,
AuthError::DataBaseError(e.to_string()),
))
));
}
} {
true => Outcome::Success(AuthPreflag(api_key)),
Expand Down
32 changes: 32 additions & 0 deletions src/db_get/api_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ pub async fn api_key_exists(db: &DatabaseConnection, api_key: &str) -> Result<bo
}
}

pub async fn country_related_to_api_key(
db: &DatabaseConnection,
api_key: &String,
country_id: i32,
) -> Result<bool, DbErr> {
match plotsystem_api_keys::Entity::find()
.join(
JoinType::InnerJoin,
plotsystem_api_keys::Relation::PlotsystemBuildteams.def(),
)
.join(
JoinType::InnerJoin,
plotsystem_buildteams::Relation::PlotsystemBuildteamHasCountries.def(),
)
.join(
JoinType::InnerJoin,
plotsystem_buildteam_has_countries::Relation::PlotsystemCountries.def(),
)
.filter(
Condition::all()
.add(plotsystem_api_keys::Column::ApiKey.eq(api_key.to_owned()))
.add(plotsystem_countries::Column::Id.eq(country_id)),
)
.all(db)
.await?
.len()
{
0 => Ok(false),
_ => Ok(true),
}
}

pub async fn cp_related_to_api_key(
db: &DatabaseConnection,
api_key: &String,
Expand Down
18 changes: 18 additions & 0 deletions src/db_get/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use sea_orm::{DatabaseConnection, DbErr};

use crate::entities::{prelude::*, *};
use sea_orm::entity::*;
use uuid::Uuid;

pub async fn by_uuid(
db: &DatabaseConnection,
uuid: Uuid,
) -> Result<Option<plotsystem_builders::Model>, DbErr> {
PlotsystemBuilders::find_by_id(uuid.as_hyphenated().to_string())
.one(db)
.await
}

pub async fn all(db: &DatabaseConnection) -> Result<Vec<plotsystem_builders::Model>, DbErr> {
PlotsystemBuilders::find().all(db).await
}
22 changes: 22 additions & 0 deletions src/db_get/country.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use sea_orm::{DatabaseConnection, DbErr};

use crate::entities::{prelude::*, *};

use sea_orm::entity::*;

pub async fn by_id(
db: &DatabaseConnection,
id: i32,
) -> Result<plotsystem_countries::Model, DbErr> {
match PlotsystemCountries::find_by_id(id).one(db).await? {
Some(cp) => Ok(cp),
None => Err(DbErr::RecordNotFound(format!(
"Country with id {} does not exists",
id
))),
}
}

pub async fn all(db: &DatabaseConnection) -> Result<Vec<plotsystem_countries::Model>, DbErr> {
PlotsystemCountries::find().all(db).await
}
2 changes: 2 additions & 0 deletions src/db_get/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod api_keys;
pub mod builder;
pub mod city_project;
pub mod country;
pub mod ftp_configuration;
pub mod plot;
pub mod server;
Expand Down
12 changes: 6 additions & 6 deletions src/entities/plotsystem_builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@ pub struct Model {
pub name: String,
pub score: i32,
pub completed_plots: i32,
pub first_slot_id: Option<i32>,
pub second_slot_id: Option<i32>,
pub third_slot_id: Option<i32>,
pub first_slot: Option<i32>,
pub second_slot: Option<i32>,
pub third_slot: Option<i32>,
pub lang: Option<String>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::plotsystem_plots::Entity",
from = "Column::FirstSlotId",
from = "Column::FirstSlot",
to = "super::plotsystem_plots::Column::Id",
on_update = "Restrict",
on_delete = "Restrict"
)]
PlotsystemPlots3,
#[sea_orm(
belongs_to = "super::plotsystem_plots::Entity",
from = "Column::SecondSlotId",
from = "Column::SecondSlot",
to = "super::plotsystem_plots::Column::Id",
on_update = "Restrict",
on_delete = "Restrict"
)]
PlotsystemPlots2,
#[sea_orm(
belongs_to = "super::plotsystem_plots::Entity",
from = "Column::ThirdSlotId",
from = "Column::ThirdSlot",
to = "super::plotsystem_plots::Column::Id",
on_update = "Restrict",
on_delete = "Restrict"
Expand Down
2 changes: 1 addition & 1 deletion src/entities/plotsystem_city_projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct Model {
pub country_id: i32,
pub name: String,
pub description: String,
pub visible: i8,
pub visible: bool,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
Expand Down
2 changes: 1 addition & 1 deletion src/entities/plotsystem_ftp_configurations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
pub schematic_path: Option<String>,
pub schematics_path: Option<String>,
pub address: String,
pub port: i32,
#[sea_orm(column_name = "isSFTP")]
Expand Down
12 changes: 6 additions & 6 deletions src/entities/sea_orm_active_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ pub enum Status {
)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "continent")]
pub enum Continent {
#[sea_orm(string_value = "Europe")]
#[sea_orm(string_value = "europe")]
Europe,
#[sea_orm(string_value = "Asia")]
#[sea_orm(string_value = "asia")]
Asia,
#[sea_orm(string_value = "Africa")]
#[sea_orm(string_value = "africa")]
Africa,
#[sea_orm(string_value = "Oceania")]
#[sea_orm(string_value = "oceania")]
Oceania,
#[sea_orm(string_value = "South America")]
#[sea_orm(string_value = "south america")]
SouthAmerica,
#[sea_orm(string_value = "North America")]
#[sea_orm(string_value = "north america")]
NorthAmerica,
}
29 changes: 21 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,28 @@ fn rocket() -> _ {
rocket::build().attach(Db::init()).mount(
"/api/v1",
routes![
routes::get::ftp_configuration,
routes::get::city_project,
routes::get::city_projects,
routes::cities::city_get_all,
routes::cities::city_get,
routes::cities::city_post,
routes::cities::city_put,
routes::cities::city_delete,
routes::builders::builders_get_all,
routes::builders::builders_get,
routes::countries::country_get_all,
routes::countries::country_get,
routes::ftp::ftp_get,
routes::plots::plot_get,
routes::plots::plots_get,
routes::plots::plot_add,
routes::plots::set_pasted,
// routes::get::ftp_configuration,
// routes::get::city_project,
routes::get::server,
routes::get::plot,
routes::get::plots,
routes::get::byte_arr,
routes::post::plot_add,
routes::put::set_pasted,
// routes::get::plot,
// routes::get::plots,
// routes::get::byte_arr,
// routes::post::plot_add,
// routes::put::set_pasted,
],
)
}
64 changes: 64 additions & 0 deletions src/routes/builders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::auth::auth_preflag_request_guard::AuthPreflag;
use crate::{db_get, entities::*, pool::Db};
use rocket::Request;
use rocket::{http::Status, response, response::Responder, response::Response, serde::json::Json};
use sea_orm::{ActiveValue::*, EntityTrait};
use sea_orm_rocket::Connection;
use serde::Deserialize;
use uuid::Uuid;

pub struct APIResponse<R>(pub Status, pub Option<R>);

impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for APIResponse<R> {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
let mut build = Response::build();
if let Some(responder) = self.1 {
build.merge(responder.respond_to(req)?);
}

build.status(self.0).ok()
}
}

#[get("/builders")]
pub async fn builders_get_all(
conn: Connection<'_, Db>,
) -> Result<Json<Vec<plotsystem_builders::Model>>, APIResponse<String>> {
Copy link
Collaborator

@jokil123 jokil123 Aug 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not return an APIResponse in both cases (like in function builders_get) for more code consistency

let db = conn.into_inner();

match db_get::builder::all(db).await {
Ok(builders) => Ok(Json(builders)),
Err(e) => Err(APIResponse(
Status::InternalServerError,
Some(e.to_string()),
)),
}
}

#[get("/builder/<uuid>")]
pub async fn builders_get(
conn: Connection<'_, Db>,
uuid: String,
) -> Result<APIResponse<Json<plotsystem_builders::Model>>, APIResponse<String>> {
let db = conn.into_inner();

let parsed_uuid = Uuid::parse_str(&uuid);

if parsed_uuid.is_err() {
return Err(APIResponse(Status::BadRequest, None));
}

match db_get::builder::by_uuid(db, parsed_uuid.unwrap()).await {
Ok(builder) => {
if (builder.is_none()) {
Ok(APIResponse(Status::NotFound, None))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unsucessful API request shouldnt return the Ok() Variant. Return an error instead.

Suggested change
Ok(APIResponse(Status::NotFound, None))
Err(APIResponse(Status::NotFound, None))

} else {
Ok(APIResponse(Status::Ok, Some(Json(builder.unwrap()))))
}
Comment on lines +53 to +57
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use match syntax here instead.

Suggested change
if (builder.is_none()) {
Ok(APIResponse(Status::NotFound, None))
} else {
Ok(APIResponse(Status::Ok, Some(Json(builder.unwrap()))))
}
match builder {
Some(b) => {
Ok(APIResponse(Status::Ok, Some(Json(b.unwrap()))))
},
None => {
Ok(APIResponse(Status::NotFound, None))
}
}

}
Err(e) => Err(APIResponse(
Status::InternalServerError,
Some(e.to_string()),
)),
}
}
Loading