mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2024-12-26 07:05:57 -05:00
Implement request guards for organization
This commit is contained in:
parent
ed97725c8b
commit
4d50014e35
@ -6,7 +6,7 @@ use db::DbConn;
|
|||||||
use db::models::*;
|
use db::models::*;
|
||||||
|
|
||||||
use api::{PasswordData, JsonResult, EmptyResult, NumberOrString};
|
use api::{PasswordData, JsonResult, EmptyResult, NumberOrString};
|
||||||
use auth::Headers;
|
use auth::{Headers, AdminHeaders, OwnerHeaders};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -82,11 +82,7 @@ fn delete_organization(org_id: String, data: Json<PasswordData>, headers: Header
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>")]
|
#[get("/organizations/<org_id>")]
|
||||||
fn get_organization(org_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_organization(org_id: String, headers: OwnerHeaders, conn: DbConn) -> JsonResult {
|
||||||
if UserOrganization::find_by_user_and_org( &headers.user.uuid, &org_id, &conn).is_none() {
|
|
||||||
err!("User not in Organization or Organization doesn't exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
match Organization::find_by_uuid(&org_id, &conn) {
|
match Organization::find_by_uuid(&org_id, &conn) {
|
||||||
Some(organization) => Ok(Json(organization.to_json())),
|
Some(organization) => Ok(Json(organization.to_json())),
|
||||||
None => err!("Can't find organization details")
|
None => err!("Can't find organization details")
|
||||||
@ -132,7 +128,7 @@ fn get_user_collections(headers: Headers, conn: DbConn) -> JsonResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/collections")]
|
#[get("/organizations/<org_id>/collections")]
|
||||||
fn get_org_collections(org_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_org_collections(org_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
|
||||||
Ok(Json(json!({
|
Ok(Json(json!({
|
||||||
"Data":
|
"Data":
|
||||||
Collection::find_by_organization(&org_id, &conn)
|
Collection::find_by_organization(&org_id, &conn)
|
||||||
@ -226,7 +222,7 @@ fn post_organization_collection_delete(org_id: String, col_id: String, headers:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
|
#[get("/organizations/<org_id>/collections/<coll_id>/details")]
|
||||||
fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
|
||||||
match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) {
|
match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) {
|
||||||
None => err!("Collection not found"),
|
None => err!("Collection not found"),
|
||||||
Some(collection) => Ok(Json(collection.to_json()))
|
Some(collection) => Ok(Json(collection.to_json()))
|
||||||
@ -234,7 +230,7 @@ fn get_org_collection_detail(org_id: String, coll_id: String, headers: Headers,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/collections/<coll_id>/users")]
|
#[get("/organizations/<org_id>/collections/<coll_id>/users")]
|
||||||
fn get_collection_users(org_id: String, coll_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_collection_users(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
|
||||||
// Get org and collection, check that collection is from org
|
// Get org and collection, check that collection is from org
|
||||||
|
|
||||||
// Get the users from collection
|
// Get the users from collection
|
||||||
@ -278,7 +274,7 @@ fn get_org_details(data: OrgIdData, headers: Headers, conn: DbConn) -> JsonResul
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/users")]
|
#[get("/organizations/<org_id>/users")]
|
||||||
fn get_org_users(org_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_org_users(org_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
|
||||||
match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) {
|
match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) {
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
None => err!("User isn't member of organization")
|
None => err!("User isn't member of organization")
|
||||||
@ -408,13 +404,7 @@ fn confirm_invite(org_id: String, user_id: String, data: Json<Value>, headers: H
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/organizations/<org_id>/users/<user_id>")]
|
#[get("/organizations/<org_id>/users/<user_id>")]
|
||||||
fn get_user(org_id: String, user_id: String, headers: Headers, conn: DbConn) -> JsonResult {
|
fn get_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult {
|
||||||
let current_user = match UserOrganization::find_by_user_and_org(
|
|
||||||
&headers.user.uuid, &org_id, &conn) {
|
|
||||||
Some(user) => user,
|
|
||||||
None => err!("The current user isn't member of the organization")
|
|
||||||
};
|
|
||||||
|
|
||||||
let user = match UserOrganization::find_by_uuid(&user_id, &conn) {
|
let user = match UserOrganization::find_by_uuid(&user_id, &conn) {
|
||||||
Some(user) => user,
|
Some(user) => user,
|
||||||
None => err!("The specified user isn't member of the organization")
|
None => err!("The specified user isn't member of the organization")
|
||||||
|
102
src/auth.rs
102
src/auth.rs
@ -94,7 +94,7 @@ use rocket::Outcome;
|
|||||||
use rocket::request::{self, Request, FromRequest};
|
use rocket::request::{self, Request, FromRequest};
|
||||||
|
|
||||||
use db::DbConn;
|
use db::DbConn;
|
||||||
use db::models::{User, Device};
|
use db::models::{User, UserOrganization, UserOrgType, Device};
|
||||||
|
|
||||||
pub struct Headers {
|
pub struct Headers {
|
||||||
pub host: String,
|
pub host: String,
|
||||||
@ -155,4 +155,104 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers {
|
|||||||
|
|
||||||
Outcome::Success(Headers { host, device, user })
|
Outcome::Success(Headers { host, device, user })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OrgHeaders {
|
||||||
|
pub host: String,
|
||||||
|
pub device: Device,
|
||||||
|
pub user: User,
|
||||||
|
pub org_user_type: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders {
|
||||||
|
type Error = &'static str;
|
||||||
|
|
||||||
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||||
|
match request.guard::<Headers>() {
|
||||||
|
Outcome::Forward(f) => Outcome::Forward(f),
|
||||||
|
Outcome::Failure(f) => Outcome::Failure(f),
|
||||||
|
Outcome::Success(headers) => {
|
||||||
|
// org_id is expected to be the first dynamic param
|
||||||
|
match request.get_param::<String>(0) {
|
||||||
|
Err(_) => err_handler!("Error getting the organization id"),
|
||||||
|
Ok(org_id) => {
|
||||||
|
let conn = match request.guard::<DbConn>() {
|
||||||
|
Outcome::Success(conn) => conn,
|
||||||
|
_ => err_handler!("Error getting DB")
|
||||||
|
};
|
||||||
|
|
||||||
|
let org_user = match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) {
|
||||||
|
Some(user) => user,
|
||||||
|
None => err_handler!("The current user isn't member of the organization")
|
||||||
|
};
|
||||||
|
|
||||||
|
Outcome::Success(Self{
|
||||||
|
host: headers.host,
|
||||||
|
device: headers.device,
|
||||||
|
user: headers.user,
|
||||||
|
org_user_type: org_user.type_,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AdminHeaders {
|
||||||
|
pub host: String,
|
||||||
|
pub device: Device,
|
||||||
|
pub user: User,
|
||||||
|
pub org_user_type: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'r> FromRequest<'a, 'r> for AdminHeaders {
|
||||||
|
type Error = &'static str;
|
||||||
|
|
||||||
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||||
|
match request.guard::<OrgHeaders>() {
|
||||||
|
Outcome::Forward(f) => Outcome::Forward(f),
|
||||||
|
Outcome::Failure(f) => Outcome::Failure(f),
|
||||||
|
Outcome::Success(headers) => {
|
||||||
|
if headers.org_user_type > UserOrgType::Admin as i32 {
|
||||||
|
err_handler!("You need to be Admin or Owner to call this endpoint")
|
||||||
|
} else {
|
||||||
|
Outcome::Success(Self{
|
||||||
|
host: headers.host,
|
||||||
|
device: headers.device,
|
||||||
|
user: headers.user,
|
||||||
|
org_user_type: headers.org_user_type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OwnerHeaders {
|
||||||
|
pub host: String,
|
||||||
|
pub device: Device,
|
||||||
|
pub user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'r> FromRequest<'a, 'r> for OwnerHeaders {
|
||||||
|
type Error = &'static str;
|
||||||
|
|
||||||
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||||
|
match request.guard::<OrgHeaders>() {
|
||||||
|
Outcome::Forward(f) => Outcome::Forward(f),
|
||||||
|
Outcome::Failure(f) => Outcome::Failure(f),
|
||||||
|
Outcome::Success(headers) => {
|
||||||
|
if headers.org_user_type > UserOrgType::Owner as i32 {
|
||||||
|
err_handler!("You need to be Owner to call this endpoint")
|
||||||
|
} else {
|
||||||
|
Outcome::Success(Self{
|
||||||
|
host: headers.host,
|
||||||
|
device: headers.device,
|
||||||
|
user: headers.user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user