Browse Source

Support Manager role

pull/1222/head
Matlink 5 years ago
parent
commit
2f9ba4a4e2
  1. 59
      src/api/core/organizations.rs
  2. 41
      src/auth.rs

59
src/api/core/organizations.rs

@ -5,7 +5,7 @@ use serde_json::Value;
use crate::{
api::{EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType},
auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders},
auth::{decode_invite, AdminHeaders, Headers, OwnerHeaders, ManagerHeaders},
db::{models::*, DbConn},
mail, CONFIG,
};
@ -217,7 +217,7 @@ fn get_org_collections(org_id: String, _headers: AdminHeaders, conn: DbConn) ->
#[post("/organizations/<org_id>/collections", data = "<data>")]
fn post_organization_collections(
org_id: String,
_headers: AdminHeaders,
headers: ManagerHeaders,
data: JsonUpcase<NewCollectionData>,
conn: DbConn,
) -> JsonResult {
@ -230,6 +230,7 @@ fn post_organization_collections(
let collection = Collection::new(org.uuid, data.Name);
collection.save(&conn)?;
CollectionUser::save(&headers.user.uuid, &collection.uuid, false, false, &conn)?;
Ok(Json(collection.to_json()))
}
@ -317,10 +318,14 @@ fn post_organization_collection_delete_user(
}
#[delete("/organizations/<org_id>/collections/<col_id>")]
fn delete_organization_collection(org_id: String, col_id: String, _headers: AdminHeaders, conn: DbConn) -> EmptyResult {
fn delete_organization_collection(org_id: String, col_id: String, headers: ManagerHeaders, conn: DbConn) -> EmptyResult {
match Collection::find_by_uuid(&col_id, &conn) {
None => err!("Collection not found"),
Some(collection) => {
match check_manager_in_collection(&org_id, &col_id, &headers.user.uuid, &conn) {
Err(_error) => err!("You have no permission to edit this collection"),
Ok(result) => result,
}
if collection.org_uuid == org_id {
collection.delete(&conn)
} else {
@ -341,7 +346,7 @@ struct DeleteCollectionData {
fn post_organization_collection_delete(
org_id: String,
col_id: String,
headers: AdminHeaders,
headers: ManagerHeaders,
_data: JsonUpcase<DeleteCollectionData>,
conn: DbConn,
) -> EmptyResult {
@ -349,7 +354,12 @@ fn post_organization_collection_delete(
}
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
fn get_org_collection_detail(org_id: String, coll_id: String, headers: ManagerHeaders, conn: DbConn) -> JsonResult {
match check_manager_in_collection(&org_id, &coll_id, &headers.user.uuid, &conn) {
Err(_error) => err!("You have no permission to edit this collection"),
Ok(result) => result,
}
match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) {
None => err!("Collection not found"),
Some(collection) => {
@ -363,13 +373,18 @@ fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHead
}
#[get("/organizations/<org_id>/collections/<coll_id>/users")]
fn get_collection_users(org_id: String, coll_id: String, _headers: AdminHeaders, conn: DbConn) -> JsonResult {
fn get_collection_users(org_id: String, coll_id: String, headers: ManagerHeaders, conn: DbConn) -> JsonResult {
// Get org and collection, check that collection is from org
let collection = match Collection::find_by_uuid_and_org(&coll_id, &org_id, &conn) {
None => err!("Collection not found in Organization"),
Some(collection) => collection,
};
match check_manager_in_collection(&org_id, &coll_id, &headers.user.uuid, &conn) {
Err(_error) => err!("You have no permission to edit this collection"),
Ok(result) => result,
}
// Get the users from collection
let user_list: Vec<Value> = CollectionUser::find_by_collection(&collection.uuid, &conn)
.iter()
@ -388,7 +403,7 @@ fn put_collection_users(
org_id: String,
coll_id: String,
data: JsonUpcaseVec<CollectionData>,
_headers: AdminHeaders,
headers: ManagerHeaders,
conn: DbConn,
) -> EmptyResult {
// Get org and collection, check that collection is from org
@ -396,6 +411,12 @@ fn put_collection_users(
err!("Collection not found in Organization")
}
match check_manager_in_collection(&org_id, &coll_id, &headers.user.uuid, &conn) {
Err(_error) => err!("You have no permission to edit this collection"),
Ok(result) => result,
}
// Delete all the user-collections
CollectionUser::delete_all_by_collection(&coll_id, &conn)?;
@ -440,7 +461,7 @@ fn get_org_details(data: Form<OrgIdData>, headers: Headers, conn: DbConn) -> Jso
}
#[get("/organizations/<org_id>/users")]
fn get_org_users(org_id: String, _headers: AdminHeaders, conn: DbConn) -> JsonResult {
fn get_org_users(org_id: String, _headers: ManagerHeaders, conn: DbConn) -> JsonResult {
let users = UserOrganization::find_by_org(&org_id, &conn);
let users_json: Vec<Value> = users.iter().map(|c| c.to_json_user_details(&conn)).collect();
@ -1043,4 +1064,24 @@ fn get_plans(_headers: Headers, _conn: DbConn) -> JsonResult {
],
"ContinuationToken": null
})))
}
}
fn check_manager_in_collection(org_id: &str, col_id: &str, user_id: &str, conn: &DbConn) -> EmptyResult {
// Check current manager is in collection
let col_user = match CollectionUser::find_by_collection_and_user(&col_id, &user_id, &conn) {
None => err!("Manager not in Collection"),
Some(col_user) => col_user,
};
// Check current manager is manager of that the org
let user_org = match UserOrganization::find_by_user_and_org(&col_user.user_uuid, &org_id, &conn) {
None => err!("User is not manager of the Organisation"),
Some(user_org) => user_org,
};
if user_org.atype != UserOrgType::Manager {
err!("Current user is not manager")
}
Ok(())
}

41
src/auth.rs

@ -379,6 +379,47 @@ impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders {
}
}
pub struct ManagerHeaders {
pub host: String,
pub device: Device,
pub user: User,
pub org_user_type: UserOrgType,
}
impl<'a, 'r> FromRequest<'a, 'r> for ManagerHeaders {
type Error = &'static str;
fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
match request.guard::<OrgHeaders>() {
Outcome::Forward(_) => Outcome::Forward(()),
Outcome::Failure(f) => Outcome::Failure(f),
Outcome::Success(headers) => {
if headers.org_user_type >= UserOrgType::Manager {
Outcome::Success(Self {
host: headers.host,
device: headers.device,
user: headers.user,
org_user_type: headers.org_user_type,
})
} else {
err_handler!("You need to be Manager, Admin or Owner to call this endpoint")
}
}
}
}
}
impl Into<Headers> for ManagerHeaders {
fn into(self) -> Headers {
Headers {
host: self.host,
device: self.device,
user: self.user,
}
}
}
pub struct AdminHeaders {
pub host: String,
pub device: Device,

Loading…
Cancel
Save