mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-19 15:33:54 +02:00
3119 lines
94 KiB
Rust
3119 lines
94 KiB
Rust
//! The V1 API things!
|
|
|
|
use axum::extract::{Path, State};
|
|
use axum::http::{HeaderMap, HeaderValue};
|
|
use axum::middleware::from_fn;
|
|
use axum::response::{IntoResponse, Response};
|
|
use axum::routing::{delete, get, post, put};
|
|
use axum::{Extension, Json, Router};
|
|
use compact_jwt::{Jws, JwsSigner};
|
|
use kanidm_proto::constants::uri::V1_AUTH_VALID;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::net::IpAddr;
|
|
use uuid::Uuid;
|
|
|
|
use kanidm_proto::internal::{
|
|
ApiToken, AppLink, CUIntentToken, CURequest, CUSessionToken, CUStatus, CreateRequest,
|
|
CredentialStatus, DeleteRequest, IdentifyUserRequest, IdentifyUserResponse, ModifyRequest,
|
|
RadiusAuthToken, SearchRequest, SearchResponse, UserAuthToken,
|
|
};
|
|
use kanidm_proto::v1::{
|
|
AccountUnixExtend, ApiTokenGenerate, AuthIssueSession, AuthRequest, AuthResponse,
|
|
AuthState as ProtoAuthState, Entry as ProtoEntry, GroupUnixExtend, SingleStringRequest,
|
|
UatStatus, UnixGroupToken, UnixUserToken, WhoamiResponse,
|
|
};
|
|
use kanidmd_lib::idm::event::AuthResult;
|
|
use kanidmd_lib::idm::AuthState;
|
|
use kanidmd_lib::prelude::*;
|
|
use kanidmd_lib::value::PartialValue;
|
|
|
|
use super::apidocs::path_schema;
|
|
use super::errors::WebError;
|
|
use super::middleware::caching::{cache_me, dont_cache_me};
|
|
use super::middleware::KOpId;
|
|
use super::ServerState;
|
|
use crate::https::apidocs::response_schema::{ApiResponseWithout200, DefaultApiResponse};
|
|
use crate::https::extractors::{TrustedClientIp, VerifiedClientInformation};
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
pub(crate) struct SessionId {
|
|
pub sessionid: Uuid,
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/raw/create",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
request_body=CreateRequest,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/raw",
|
|
)]
|
|
/// Raw request to the system, be warned this can be dangerous!
|
|
pub async fn raw_create(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(msg): Json<CreateRequest>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_create(client_auth_info, msg, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/raw/modify",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
request_body=ModifyRequest,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/raw",
|
|
)]
|
|
/// Raw request to the system, be warned this can be dangerous!
|
|
pub async fn raw_modify(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(msg): Json<ModifyRequest>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_modify(client_auth_info, msg, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/raw/delete",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
request_body=DeleteRequest,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/raw",
|
|
)]
|
|
/// Raw request to the system, be warned this can be dangerous!
|
|
pub async fn raw_delete(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(msg): Json<DeleteRequest>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_delete(client_auth_info, msg, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/raw/search",
|
|
responses(
|
|
(status = 200), // TODO: response content
|
|
ApiResponseWithout200,
|
|
),
|
|
request_body=SearchRequest,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/raw",
|
|
)]
|
|
/// Raw request to the system, be warned this can be dangerous!
|
|
pub async fn raw_search(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(msg): Json<SearchRequest>,
|
|
) -> Result<Json<SearchResponse>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_search(client_auth_info, msg, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/self",
|
|
responses(
|
|
(status = 200), // TODO: response content
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/self",
|
|
)]
|
|
// Whoami?
|
|
pub async fn whoami(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<WhoamiResponse>, WebError> {
|
|
// New event, feed current auth data from the token to it.
|
|
state
|
|
.qe_r_ref
|
|
.handle_whoami(client_auth_info, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/self/_uat",
|
|
responses(
|
|
(status = 200, description = "Ok"),
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/self",
|
|
)]
|
|
pub async fn whoami_uat(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<UserAuthToken>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_whoami_uat(client_auth_info, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/logout",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/auth",
|
|
)]
|
|
pub async fn logout(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_logout(client_auth_info, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
// // =============== REST generics ========================
|
|
|
|
#[instrument(level = "trace", skip(state, kopid))]
|
|
pub async fn json_rest_event_get(
|
|
state: ServerState,
|
|
attrs: Option<Vec<String>>,
|
|
filter: Filter<FilterInvalid>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearch(client_auth_info, filter, attrs, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_get_id(
|
|
state: ServerState,
|
|
id: String,
|
|
filter: Filter<FilterInvalid>,
|
|
attrs: Option<Vec<String>>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
let filter = Filter::join_parts_and(filter, filter_all!(f_id(id.as_str())));
|
|
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearch(client_auth_info, filter, attrs, kopid.eventid)
|
|
.await
|
|
.map(|mut r| r.pop())
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_delete_id(
|
|
state: ServerState,
|
|
id: String,
|
|
filter: Filter<FilterInvalid>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = Filter::join_parts_and(filter, filter_all!(f_id(id.as_str())));
|
|
state
|
|
.qe_w_ref
|
|
.handle_internaldelete(client_auth_info, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_get_attr(
|
|
state: ServerState,
|
|
id: &str,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = Filter::join_parts_and(filter, filter_all!(f_id(id)));
|
|
let attrs = Some(vec![attr.clone()]);
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearch(client_auth_info, filter, attrs, kopid.eventid)
|
|
.await
|
|
.map(|mut event_result| event_result.pop().and_then(|mut e| e.attrs.remove(&attr)))
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_get_id_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
json_rest_event_get_attr(state, id.as_str(), attr, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
pub async fn json_rest_event_post(
|
|
state: ServerState,
|
|
classes: Vec<String>,
|
|
obj: ProtoEntry,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
debug_assert!(!classes.is_empty());
|
|
|
|
let mut obj = obj;
|
|
obj.attrs.insert(Attribute::Class.to_string(), classes);
|
|
let msg = CreateRequest {
|
|
entries: vec![obj.to_owned()],
|
|
};
|
|
|
|
state
|
|
.qe_w_ref
|
|
.handle_create(client_auth_info, msg, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_post_id_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Vec<String>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_appendattribute(client_auth_info, id, attr, values, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_put_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Vec<String>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_setattribute(client_auth_info, id, attr, values, filter, kopid.eventid)
|
|
.await
|
|
.map_err(WebError::from)
|
|
.map(Json::from)
|
|
}
|
|
|
|
pub async fn json_rest_event_post_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Vec<String>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_appendattribute(client_auth_info, id, attr, values, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
// Okay, so a put normally needs
|
|
/// * filter of what we are working on (id + class)
|
|
/// * a `Map<String, Vec<String>>` that we turn into a modlist.
|
|
///
|
|
/// OR
|
|
/// * filter of what we are working on (id + class)
|
|
/// * a `Vec<String>` that we are changing
|
|
/// * the attr name (as a param to this in path)
|
|
///
|
|
pub async fn json_rest_event_put_id_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Vec<String>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
json_rest_event_put_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
pub async fn json_rest_event_delete_id_attr(
|
|
state: ServerState,
|
|
id: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Option<Vec<String>>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
json_rest_event_delete_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
pub async fn json_rest_event_delete_attr(
|
|
state: ServerState,
|
|
uuid_or_name: String,
|
|
attr: String,
|
|
filter: Filter<FilterInvalid>,
|
|
values: Option<Vec<String>>,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<()>, WebError> {
|
|
let values = match values {
|
|
Some(val) => val,
|
|
None => vec![],
|
|
};
|
|
|
|
if values.is_empty() {
|
|
state
|
|
.qe_w_ref
|
|
.handle_purgeattribute(client_auth_info, uuid_or_name, attr, filter, kopid.eventid)
|
|
.await
|
|
} else {
|
|
state
|
|
.qe_w_ref
|
|
.handle_removeattributevalues(
|
|
client_auth_info,
|
|
uuid_or_name,
|
|
attr,
|
|
values,
|
|
filter,
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
}
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/schema",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/schema",
|
|
)]
|
|
// Whoami?
|
|
pub async fn schema_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
// NOTE: This is filter_all, because from_internal_message will still do the alterations
|
|
// needed to make it safe. This is needed because there may be aci's that block access
|
|
// to the recycle/ts types in the filter, and we need the aci to only eval on this
|
|
// part of the filter!
|
|
let filter = filter_all!(f_or!([
|
|
f_eq(Attribute::Class, EntryClass::AttributeType.into()),
|
|
f_eq(Attribute::Class, EntryClass::ClassType.into())
|
|
]));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/schema/attributetype",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/schema",
|
|
)]
|
|
pub async fn schema_attributetype_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::AttributeType.into()));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/schema/attributetype/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/schema",
|
|
)]
|
|
pub async fn schema_attributetype_get_id(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
// These can't use get_id because the attribute name and class name aren't ... well name.
|
|
let filter = filter_all!(f_and!([
|
|
f_eq(Attribute::Class, EntryClass::AttributeType.into()),
|
|
f_eq(
|
|
Attribute::AttributeName,
|
|
PartialValue::new_iutf8(id.as_str())
|
|
)
|
|
]));
|
|
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearch(client_auth_info, filter, None, kopid.eventid)
|
|
.await
|
|
.map(|mut r| r.pop())
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/schema/classtype",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/schema",
|
|
)]
|
|
pub async fn schema_classtype_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::ClassType.into()));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/schema/classtype/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/schema",
|
|
)]
|
|
pub async fn schema_classtype_get_id(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
// These can't use get_id because they attribute name and class name aren't ... well name.
|
|
let filter = filter_all!(f_and!([
|
|
f_eq(Attribute::Class, EntryClass::ClassType.into()),
|
|
f_eq(Attribute::ClassName, PartialValue::new_iutf8(id.as_str()))
|
|
]));
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearch(client_auth_info, filter, None, kopid.eventid)
|
|
.await
|
|
.map(|mut r| r.pop())
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn person_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Person.into()));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
// request_body=ProtoEntry, // TODO: ProtoEntry can't be serialized, so we need to do this manually
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
/// Expects the following fields in the attrs field of the req: [name, displayname]
|
|
pub async fn person_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<ProtoEntry>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let classes: Vec<String> = vec![
|
|
EntryClass::Person.into(),
|
|
EntryClass::Account.into(),
|
|
EntryClass::Object.into(),
|
|
];
|
|
json_rest_event_post(state, classes, obj, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn person_id_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Person.into()));
|
|
json_rest_event_get_id(state, id, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn person_id_delete(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Person.into()));
|
|
json_rest_event_delete_id(state, id, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
// // == account ==
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::ServiceAccount.into()));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account",
|
|
// request_body=Json, // TODO ProtoEntry can't be serialized, so we need to do this manually
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<ProtoEntry>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let classes: Vec<String> = vec![
|
|
EntryClass::ServiceAccount.into(),
|
|
EntryClass::Account.into(),
|
|
EntryClass::Object.into(),
|
|
];
|
|
json_rest_event_post(state, classes, obj, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
patch,
|
|
path = "/v1/service_account/{id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
// request_body=ProtoEntry, // TODO: can't deal with a HashMap in the attr
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_patch(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(obj): Json<ProtoEntry>,
|
|
) -> Result<Json<()>, WebError> {
|
|
// Update a value / attrs
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
let filter = Filter::join_parts_and(filter, filter_all!(f_id(id.as_str())));
|
|
state
|
|
.qe_w_ref
|
|
.handle_internalpatch(client_auth_info, filter, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::ServiceAccount.into()));
|
|
json_rest_event_get_id(state, id, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/service_account/{id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_delete(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::ServiceAccount.into()));
|
|
json_rest_event_delete_id(state, id, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_credential/_generate",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_credential_generate(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<String>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_service_account_credential_generate(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account/{id}/_into_person",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
/// Due to how the migrations work in 6 -> 7, we can accidentally
|
|
/// mark "accounts" as service accounts when they are persons. This
|
|
/// allows migrating them to the person type due to its similarities.
|
|
///
|
|
/// In the future this will be REMOVED!
|
|
#[deprecated]
|
|
pub async fn service_account_into_person(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_service_account_into_person(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_spi_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_api_token_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Vec<ApiToken>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_service_account_api_token_get(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account/{id}/_spi_token",
|
|
request_body = ApiTokenGenerate,
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_api_token_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(obj): Json<ApiTokenGenerate>,
|
|
) -> Result<Json<String>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_service_account_api_token_generate(
|
|
client_auth_info,
|
|
id,
|
|
obj.label,
|
|
obj.expiry,
|
|
obj.read_write,
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/service_account/{id}/_spi_token/{token_id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_api_token_delete(
|
|
State(state): State<ServerState>,
|
|
Path((id, token_id)): Path<(String, Uuid)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_service_account_api_token_destroy(client_auth_info, id, token_id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_attr/{attr}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
(status = 403, description = "Authorzation refused"),
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/attr",
|
|
)]
|
|
pub async fn person_id_get_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_get_attr(state, id.as_str(), attr, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_attr/{attr}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_get_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_get_attr(state, id.as_str(), attr, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_attr/{attr}",
|
|
request_body= Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/attr",
|
|
)]
|
|
pub async fn person_id_post_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_post_id_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account/{id}/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_post_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_post_id_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}/_attr/{attr}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/attr",
|
|
)]
|
|
pub async fn person_id_delete_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_delete_id_attr(state, id, attr, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/service_account/{id}/_attr/{attr}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_delete_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_delete_id_attr(state, id, attr, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/person/{id}/_attr/{attr}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/attr",
|
|
)]
|
|
pub async fn person_id_put_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_put_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/service_account/{id}/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_put_attr(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_put_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
patch,
|
|
path = "/v1/person/{id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
// request_body=ProtoEntry, // TODO: can't deal with a HashMap in the attr
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn person_id_patch(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(obj): Json<ProtoEntry>,
|
|
) -> Result<Json<()>, WebError> {
|
|
// Update a value / attrs
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
let filter = Filter::join_parts_and(filter, filter_all!(f_id(id.as_str())));
|
|
state
|
|
.qe_w_ref
|
|
.handle_internalpatch(client_auth_info, filter, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_credential/_update",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/credential",
|
|
)]
|
|
pub async fn person_id_credential_update_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<(CUSessionToken, CUStatus)>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialupdate(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_credential/_update_intent/{ttl}",
|
|
params(
|
|
("ttl" = u64, description="The new TTL for the credential?")
|
|
),
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/credential",
|
|
)]
|
|
// TODO: this shouldn't be a get, we're making changes!
|
|
#[instrument(level = "trace", skip(state, kopid))]
|
|
pub async fn person_id_credential_update_intent_ttl_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, ttl)): Path<(String, u64)>,
|
|
) -> Result<Json<CUIntentToken>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialupdateintent(
|
|
client_auth_info,
|
|
id,
|
|
Some(Duration::from_secs(ttl)),
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_credential/_update_intent",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
#[instrument(level = "trace", skip(state, kopid))]
|
|
pub async fn person_id_credential_update_intent_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<CUIntentToken>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialupdateintent(client_auth_info, id, None, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/account/{id}/_user_auth_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
pub async fn account_id_user_auth_token_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<UatStatus>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_account_user_auth_token_get(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/account/{id}/_user_auth_token/{token_id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
pub async fn account_user_auth_token_delete(
|
|
State(state): State<ServerState>,
|
|
Path((id, token_id)): Path<(String, Uuid)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_account_user_auth_token_destroy(client_auth_info, id, token_id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/credential/_exchange_intent",
|
|
params(
|
|
),
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/credential",
|
|
)] // TODO: post body
|
|
pub async fn credential_update_exchange_intent(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(intent_token): Json<CUIntentToken>,
|
|
) -> Result<Json<(CUSessionToken, CUStatus)>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialexchangeintent(intent_token, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/credential/_status",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/credential",
|
|
)] // TODO: post body
|
|
pub async fn credential_update_status(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(session_token): Json<CUSessionToken>,
|
|
) -> Result<Json<CUStatus>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_idmcredentialupdatestatus(session_token, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/credential/_update",
|
|
responses(
|
|
(status=200, body=CUStatus), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/credential",
|
|
)] // TODO: post body
|
|
#[instrument(level = "debug", skip(state, kopid))]
|
|
pub async fn credential_update_update(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(cubody): Json<Vec<serde_json::Value>>,
|
|
) -> Result<Json<CUStatus>, WebError> {
|
|
let scr: CURequest = match serde_json::from_value(cubody[0].clone()) {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
let errmsg = format!("Failed to deserialize CURequest: {:?}", err);
|
|
error!("{}", errmsg);
|
|
return Err(WebError::InternalServerError(errmsg));
|
|
}
|
|
};
|
|
let session_token = match serde_json::from_value(cubody[1].clone()) {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
let errmsg = format!("Failed to deserialize session token: {:?}", err);
|
|
error!("{}", errmsg);
|
|
return Err(WebError::InternalServerError(errmsg));
|
|
}
|
|
};
|
|
debug!("session_token: {:?}", session_token);
|
|
debug!("scr: {:?}", scr);
|
|
state
|
|
.qe_r_ref
|
|
.handle_idmcredentialupdate(session_token, scr, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/credential/_commit",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/credential",
|
|
)] // TODO: post body
|
|
pub async fn credential_update_commit(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(session_token): Json<CUSessionToken>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialupdatecommit(session_token, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/credential/_cancel",
|
|
request_body=CUSessionToken,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/credential",
|
|
)]
|
|
pub async fn credential_update_cancel(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(session_token): Json<CUSessionToken>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmcredentialupdatecancel(session_token, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_credential/_status",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_credential_status_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<CredentialStatus>, WebError> {
|
|
match state
|
|
.qe_r_ref
|
|
.handle_idmcredentialstatus(client_auth_info, id.clone(), kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
{
|
|
Ok(val) => Ok(val),
|
|
Err(err) => {
|
|
if let OperationError::NoMatchingAttributes = err {
|
|
debug!("No credentials set on account {}, returning empty list", id);
|
|
Ok(Json(CredentialStatus { creds: Vec::new() }))
|
|
} else {
|
|
Err(WebError::from(err))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}/_credential/_status",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/credential",
|
|
)]
|
|
pub async fn person_get_id_credential_status(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<CredentialStatus>, WebError> {
|
|
match state
|
|
.qe_r_ref
|
|
.handle_idmcredentialstatus(client_auth_info, id.clone(), kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
{
|
|
Ok(val) => Ok(val),
|
|
Err(err) => {
|
|
if let OperationError::NoMatchingAttributes = err {
|
|
debug!("No credentials set on person {}, returning empty list", id);
|
|
Ok(Json(CredentialStatus { creds: Vec::new() }))
|
|
} else {
|
|
Err(WebError::from(err))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_ssh_pubkeys",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/ssh_pubkeys",
|
|
)]
|
|
pub async fn person_id_ssh_pubkeys_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Vec<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeyread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/account/{id}/_ssh_pubkeys",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
#[deprecated]
|
|
pub async fn account_id_ssh_pubkeys_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Vec<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeyread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_ssh_pubkeys",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_ssh_pubkeys_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Vec<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeyread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_ssh_pubkeys",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/ssh_pubkeys",
|
|
)]
|
|
pub async fn person_id_ssh_pubkeys_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json((tag, key)): Json<(String, String)>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
// Add a msg here
|
|
state
|
|
.qe_w_ref
|
|
.handle_sshkeycreate(client_auth_info, id, &tag, &key, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account/{id}/_ssh_pubkeys",
|
|
request_body = (String, String),
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_ssh_pubkeys_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json((tag, key)): Json<(String, String)>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
// Add a msg here
|
|
state
|
|
.qe_w_ref
|
|
.handle_sshkeycreate(client_auth_info, id, &tag, &key, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_ssh_pubkeys/{tag}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/ssh_pubkeys/tag",
|
|
)]
|
|
pub async fn person_id_ssh_pubkeys_tag_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, tag)): Path<(String, String)>,
|
|
) -> Result<Json<Option<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeytagread(client_auth_info, id, tag, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/account/{id}/_ssh_pubkeys/{tag}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
pub async fn account_id_ssh_pubkeys_tag_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, tag)): Path<(String, String)>,
|
|
) -> Result<Json<Option<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeytagread(client_auth_info, id, tag, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/service_account/{id}/_ssh_pubkeys/{tag}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
pub async fn service_account_id_ssh_pubkeys_tag_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, tag)): Path<(String, String)>,
|
|
) -> Result<Json<Option<String>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsshkeytagread(client_auth_info, id, tag, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}/_ssh_pubkeys/{tag}",
|
|
params(
|
|
("tag" = String, description="The tag of the SSH key"),
|
|
),
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/ssh_pubkeys/tag",
|
|
)]
|
|
pub async fn person_id_ssh_pubkeys_tag_delete(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, tag)): Path<(String, String)>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let values = vec![tag];
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
state
|
|
.qe_w_ref
|
|
.handle_removeattributevalues(
|
|
client_auth_info,
|
|
id,
|
|
Attribute::SshPublicKey.to_string(),
|
|
values,
|
|
filter,
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/service_account/{id}/_ssh_pubkeys/{tag}",
|
|
params(
|
|
("tag" = String, description="The tag of the SSH key"),
|
|
),
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn service_account_id_ssh_pubkeys_tag_delete(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path((id, tag)): Path<(String, String)>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let values = vec![tag];
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
state
|
|
.qe_w_ref
|
|
.handle_removeattributevalues(
|
|
client_auth_info,
|
|
id,
|
|
Attribute::SshPublicKey.to_string(),
|
|
values,
|
|
filter,
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_radius",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/radius",
|
|
)]
|
|
/// Get and return a single str
|
|
pub async fn person_id_radius_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Option<String>>, WebError> {
|
|
// TODO: string
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalradiusread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_radius",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/radius",
|
|
)]
|
|
// TODO: what body do we take here?
|
|
pub async fn person_id_radius_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<String>, WebError> {
|
|
// Need to to send the regen msg
|
|
state
|
|
.qe_w_ref
|
|
.handle_regenerateradius(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}/_radius",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)]
|
|
pub async fn person_id_radius_delete(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let attr = "radius_secret".to_string();
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Account.into()));
|
|
json_rest_event_delete_id_attr(state, id, attr, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
// /v1/person/:id/_radius/_token
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/person/{id}/_radius/_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/radius",
|
|
)]
|
|
pub async fn person_id_radius_token_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<RadiusAuthToken>, WebError> {
|
|
person_id_radius_handler(state, id, kopid, client_auth_info).await
|
|
}
|
|
|
|
// /v1/account/:id/_radius/_token
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/account/{id}/_radius/_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
pub async fn account_id_radius_token_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<RadiusAuthToken>, WebError> {
|
|
person_id_radius_handler(state, id, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/account/{id}/_radius/_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)] // TODO: what body do we expect here?
|
|
pub async fn account_id_radius_token_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<RadiusAuthToken>, WebError> {
|
|
person_id_radius_handler(state, id, kopid, client_auth_info).await
|
|
}
|
|
|
|
async fn person_id_radius_handler(
|
|
state: ServerState,
|
|
id: String,
|
|
kopid: KOpId,
|
|
client_auth_info: ClientAuthInfo,
|
|
) -> Result<Json<RadiusAuthToken>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalradiustokenread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_unix",
|
|
request_body=Jaon<AccountUnixExtend>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/unix",
|
|
)]
|
|
#[instrument(name = "account_post_id_unix", level = "INFO", skip(id, state, kopid))]
|
|
pub async fn person_id_unix_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<AccountUnixExtend>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmaccountunixextend(client_auth_info, id, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/service_account/{id}/_unix",
|
|
request_body = AccountUnixExtend,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/service_account",
|
|
)]
|
|
///
|
|
#[instrument(, level = "INFO", skip(id, state, kopid))]
|
|
pub async fn service_account_id_unix_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<AccountUnixExtend>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmaccountunixextend(client_auth_info, id, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/account/{id}/_unix",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)]
|
|
/// Expects an `AccountUnixExtend` object
|
|
#[instrument(, level = "INFO", skip(id, state, kopid))]
|
|
pub async fn account_id_unix_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<AccountUnixExtend>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmaccountunixextend(client_auth_info, id, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,post,
|
|
path = "/v1/account/{id}/_unix/_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)] // TODO: what body do we expect here?
|
|
#[instrument(level = "INFO", skip_all)]
|
|
pub async fn account_id_unix_token(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<UnixUserToken>, WebError> {
|
|
// no point asking for an empty id
|
|
if id.is_empty() {
|
|
return Err(OperationError::EmptyRequest.into());
|
|
}
|
|
|
|
let res = state
|
|
.qe_r_ref
|
|
.handle_internalunixusertokenread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from);
|
|
|
|
if let Err(OperationError::InvalidAccountState(val)) = &res {
|
|
// if they're not a posix user we should just hide them
|
|
if *val == format!("Missing class: {}", "posixaccount") {
|
|
return Err(OperationError::NoMatchingEntries.into());
|
|
}
|
|
};
|
|
// the was returning a 500 error which wasn't right
|
|
if let Err(OperationError::InvalidValueState) = &res {
|
|
return Err(OperationError::NoMatchingEntries.into());
|
|
};
|
|
res.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/account/{id}/_unix/_auth",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/account",
|
|
)] // TODO: what body do we expect here?
|
|
pub async fn account_id_unix_auth_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(obj): Json<SingleStringRequest>,
|
|
) -> Result<Json<Option<UnixUserToken>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_idmaccountunixauth(client_auth_info, id, obj.value, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_unix/_credential",
|
|
request_body = SingleStringRequest,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/unix",
|
|
)] // TODO: what body do we expect here?
|
|
pub async fn person_id_unix_credential_put(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(obj): Json<SingleStringRequest>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmaccountunixsetcred(client_auth_info, id, obj.value, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/person/{id}/_unix/_credential",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person/unix",
|
|
)]
|
|
pub async fn person_id_unix_credential_delete(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::PosixAccount.into()));
|
|
state
|
|
.qe_w_ref
|
|
.handle_purgeattribute(
|
|
client_auth_info,
|
|
id,
|
|
"unix_password".to_string(),
|
|
filter,
|
|
kopid.eventid,
|
|
)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/person/{id}/_identify/_user",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/person",
|
|
)] // TODO: what body do we expect here?
|
|
pub async fn person_identify_user_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
Json(user_request): Json<IdentifyUserRequest>,
|
|
) -> Result<Json<IdentifyUserResponse>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_user_identity_verification(client_auth_info, kopid.eventid, user_request, id)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/group",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group",
|
|
)]
|
|
/// Returns all groups visible to the user
|
|
pub async fn group_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/group/{id}",
|
|
params(
|
|
path_schema::UuidOrName
|
|
),
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group",
|
|
)] // TODO: post body
|
|
pub async fn group_post(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<ProtoEntry>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let classes = vec!["group".to_string(), "object".to_string()];
|
|
json_rest_event_post(state, classes, obj, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/group/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group",
|
|
)]
|
|
pub async fn group_id_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_get_id(state, id, filter, None, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/group/{id}",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group",
|
|
)]
|
|
pub async fn group_id_delete(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_delete_id(state, id, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/group/{id}/_attr/{attr}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/attr",
|
|
)]
|
|
pub async fn group_id_attr_get(
|
|
State(state): State<ServerState>,
|
|
Path((id, attr)): Path<(String, String)>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_get_id_attr(state, id, attr, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/group/{id}/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/attr",
|
|
)]
|
|
pub async fn group_id_attr_post(
|
|
Path((id, attr)): Path<(String, String)>,
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_post_id_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/group/{id}/_attr/{attr}",
|
|
request_body=Option<Vec<String>>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/attr",
|
|
)]
|
|
pub async fn group_id_attr_delete(
|
|
Path((id, attr)): Path<(String, String)>,
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
values: Option<Json<Vec<String>>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
let values = values.map(|v| v.0);
|
|
json_rest_event_delete_id_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/group/{id}/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/attr",
|
|
)]
|
|
pub async fn group_id_attr_put(
|
|
Path((id, attr)): Path<(String, String)>,
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::Group.into()));
|
|
json_rest_event_put_id_attr(state, id, attr, filter, values, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/group/{id}/_unix",
|
|
request_body = GroupUnixExtend,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/unix",
|
|
)]
|
|
pub async fn group_id_unix_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(obj): Json<GroupUnixExtend>,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_w_ref
|
|
.handle_idmgroupunixextend(client_auth_info, id, obj, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/group/{id}/_unix/_token",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/group/unix",
|
|
)]
|
|
pub async fn group_id_unix_token_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<UnixGroupToken>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalunixgrouptokenread(client_auth_info, id, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/domain",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/domain",
|
|
)]
|
|
pub async fn domain_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Uuid, PartialValue::Uuid(UUID_DOMAIN_INFO)));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/domain/_attr/{attr}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/domain",
|
|
)]
|
|
pub async fn domain_attr_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(attr): Path<String>,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::DomainInfo.into()));
|
|
json_rest_event_get_attr(
|
|
state,
|
|
STR_UUID_DOMAIN_INFO,
|
|
attr,
|
|
filter,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/domain/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/domain",
|
|
)]
|
|
pub async fn domain_attr_put(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Path(attr): Path<String>,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::DomainInfo.into()));
|
|
json_rest_event_put_attr(
|
|
state,
|
|
STR_UUID_DOMAIN_INFO.to_string(),
|
|
attr,
|
|
filter,
|
|
values,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/domain/_attr/{attr}",
|
|
request_body=Option<Vec<String>>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/domain",
|
|
)]
|
|
pub async fn domain_attr_delete(
|
|
State(state): State<ServerState>,
|
|
Path(attr): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Option<Vec<String>>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::DomainInfo.into()));
|
|
json_rest_event_delete_attr(
|
|
state,
|
|
STR_UUID_DOMAIN_INFO.to_string(),
|
|
attr,
|
|
filter,
|
|
values,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/system",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/system",
|
|
)]
|
|
pub async fn system_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_eq(
|
|
Attribute::Uuid,
|
|
PartialValue::Uuid(UUID_SYSTEM_CONFIG)
|
|
));
|
|
json_rest_event_get(state, None, filter, kopid, client_auth_info).await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/system/_attr/{attr}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/system",
|
|
)]
|
|
pub async fn system_attr_get(
|
|
State(state): State<ServerState>,
|
|
Path(attr): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<Vec<String>>>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::SystemConfig.into()));
|
|
json_rest_event_get_attr(
|
|
state,
|
|
STR_UUID_SYSTEM_CONFIG,
|
|
attr,
|
|
filter,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/system/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/system",
|
|
)]
|
|
pub async fn system_attr_post(
|
|
State(state): State<ServerState>,
|
|
Path(attr): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::SystemConfig.into()));
|
|
json_rest_event_post_attr(
|
|
state,
|
|
STR_UUID_SYSTEM_CONFIG.to_string(),
|
|
attr,
|
|
filter,
|
|
values,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
delete,
|
|
path = "/v1/system/_attr/{attr}",
|
|
request_body=Option<Vec<String>>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/system",
|
|
)]
|
|
pub async fn system_attr_delete(
|
|
State(state): State<ServerState>,
|
|
Path(attr): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Option<Vec<String>>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::SystemConfig.into()));
|
|
json_rest_event_delete_attr(
|
|
state,
|
|
STR_UUID_SYSTEM_CONFIG.to_string(),
|
|
attr,
|
|
filter,
|
|
values,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
put,
|
|
path = "/v1/system/_attr/{attr}",
|
|
request_body=Vec<String>,
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/system",
|
|
)]
|
|
pub async fn system_attr_put(
|
|
State(state): State<ServerState>,
|
|
Path(attr): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Json(values): Json<Vec<String>>,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_eq(Attribute::Class, EntryClass::SystemConfig.into()));
|
|
json_rest_event_put_attr(
|
|
state,
|
|
STR_UUID_SYSTEM_CONFIG.to_string(),
|
|
attr,
|
|
filter,
|
|
values,
|
|
kopid,
|
|
client_auth_info,
|
|
)
|
|
.await
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/recycle_bin",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/recycle_bin",
|
|
)]
|
|
pub async fn recycle_bin_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_pres(Attribute::Class));
|
|
let attrs = None;
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearchrecycled(client_auth_info, filter, attrs, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/recycle_bin/{id}",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/recycle_bin",
|
|
)]
|
|
pub async fn recycle_bin_id_get(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Option<ProtoEntry>>, WebError> {
|
|
let filter = filter_all!(f_id(id.as_str()));
|
|
let attrs = None;
|
|
|
|
state
|
|
.qe_r_ref
|
|
.handle_internalsearchrecycled(client_auth_info, filter, attrs, kopid.eventid)
|
|
.await
|
|
.map(|mut r| r.pop())
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/recycle_bin/{id}/_revive",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/recycle_bin",
|
|
)]
|
|
pub async fn recycle_bin_revive_id_post(
|
|
State(state): State<ServerState>,
|
|
Path(id): Path<String>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
let filter = filter_all!(f_id(id.as_str()));
|
|
state
|
|
.qe_w_ref
|
|
.handle_reviverecycled(client_auth_info, filter, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/self/_applinks",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/self",
|
|
)]
|
|
/// Returns your OAuth2 app links for the Web UI
|
|
pub async fn applinks_get(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<Vec<AppLink>>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_list_applinks(client_auth_info, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/reauth",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
request_body = AuthIssueSession,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/auth",
|
|
)] // TODO: post body stuff
|
|
pub async fn reauth(
|
|
State(state): State<ServerState>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(obj): Json<AuthIssueSession>,
|
|
) -> Result<Response, WebError> {
|
|
// This may change in the future ...
|
|
let inter = state
|
|
.qe_r_ref
|
|
.handle_reauth(client_auth_info, obj, kopid.eventid)
|
|
.await;
|
|
debug!("ReAuth result: {:?}", inter);
|
|
auth_session_state_management(state, inter)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/v1/auth",
|
|
responses(
|
|
(status=200), // TODO: define response
|
|
ApiResponseWithout200,
|
|
),
|
|
request_body = AuthRequest,
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/auth",
|
|
)]
|
|
pub async fn auth(
|
|
State(state): State<ServerState>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
headers: HeaderMap,
|
|
Extension(kopid): Extension<KOpId>,
|
|
Json(obj): Json<AuthRequest>,
|
|
) -> Result<Response, WebError> {
|
|
// First, deal with some state management.
|
|
// Do anything here first that's needed like getting the session details
|
|
// out of the req cookie.
|
|
|
|
let maybe_sessionid = state.get_current_auth_session_id(&headers);
|
|
debug!("Session ID: {:?}", maybe_sessionid);
|
|
// We probably need to know if we allocate the cookie, that this is a
|
|
// new session, and in that case, anything *except* authrequest init is
|
|
// invalid.
|
|
let inter = state // This may change in the future ...
|
|
.qe_r_ref
|
|
.handle_auth(maybe_sessionid, obj, kopid.eventid, client_auth_info)
|
|
.await;
|
|
debug!("Auth result: {:?}", inter);
|
|
auth_session_state_management(state, inter)
|
|
}
|
|
|
|
#[instrument(skip(state))]
|
|
fn auth_session_state_management(
|
|
state: ServerState,
|
|
inter: Result<AuthResult, OperationError>,
|
|
) -> Result<Response, WebError> {
|
|
let mut auth_session_id_tok = None;
|
|
|
|
let res: Result<AuthResponse, _> = match inter {
|
|
Ok(AuthResult {
|
|
state: auth_state,
|
|
sessionid,
|
|
}) => {
|
|
// Do some response/state management.
|
|
match auth_state {
|
|
AuthState::Choose(allowed) => {
|
|
debug!("🧩 -> AuthState::Choose"); // TODO: this should be ... less work
|
|
// Ensure the auth-session-id is set
|
|
let kref = &state.jws_signer;
|
|
let jws = Jws::into_json(&SessionId { sessionid }).map_err(|e| {
|
|
error!(?e);
|
|
OperationError::InvalidSessionState
|
|
})?;
|
|
|
|
// Get the header token ready.
|
|
kref.sign(&jws)
|
|
.map(|jwss| {
|
|
auth_session_id_tok = Some(jwss.to_string());
|
|
})
|
|
.map_err(|e| {
|
|
error!(?e);
|
|
OperationError::InvalidSessionState
|
|
})
|
|
.map(|_| ProtoAuthState::Choose(allowed))
|
|
}
|
|
AuthState::Continue(allowed) => {
|
|
debug!("🧩 -> AuthState::Continue");
|
|
let kref = &state.jws_signer;
|
|
// Get the header token ready.
|
|
let jws = Jws::into_json(&SessionId { sessionid }).map_err(|e| {
|
|
error!(?e);
|
|
OperationError::InvalidSessionState
|
|
})?;
|
|
kref.sign(&jws)
|
|
.map(|jwss| {
|
|
auth_session_id_tok = Some(jwss.to_string());
|
|
})
|
|
.map_err(|e| {
|
|
error!(?e);
|
|
OperationError::InvalidSessionState
|
|
})
|
|
.map(|_| ProtoAuthState::Continue(allowed))
|
|
}
|
|
AuthState::Success(token, issue) => {
|
|
debug!("🧩 -> AuthState::Success");
|
|
|
|
match issue {
|
|
AuthIssueSession::Token => Ok(ProtoAuthState::Success(token)),
|
|
}
|
|
}
|
|
AuthState::Denied(reason) => {
|
|
debug!("🧩 -> AuthState::Denied");
|
|
Ok(ProtoAuthState::Denied(reason))
|
|
}
|
|
}
|
|
.map(|state| AuthResponse { sessionid, state })
|
|
}
|
|
Err(e) => Err(e),
|
|
};
|
|
|
|
// if the sessionid was injected into our cookie, set it in the header too.
|
|
res.map(|response| {
|
|
let mut res = Json::from(response).into_response();
|
|
match auth_session_id_tok {
|
|
Some(tok) => {
|
|
match HeaderValue::from_str(&tok) {
|
|
Ok(val) => {
|
|
res.headers_mut().insert(KSESSIONID, val);
|
|
}
|
|
Err(err) => {
|
|
admin_error!(?err, "Failed to add sessionid {} to header", tok);
|
|
}
|
|
}
|
|
res
|
|
}
|
|
None => res,
|
|
}
|
|
})
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/auth/valid",
|
|
responses(
|
|
DefaultApiResponse,
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/auth",
|
|
)]
|
|
pub async fn auth_valid(
|
|
State(state): State<ServerState>,
|
|
Extension(kopid): Extension<KOpId>,
|
|
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
|
|
) -> Result<Json<()>, WebError> {
|
|
state
|
|
.qe_r_ref
|
|
.handle_auth_valid(client_auth_info, kopid.eventid)
|
|
.await
|
|
.map(Json::from)
|
|
.map_err(WebError::from)
|
|
}
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/v1/debug/ipinfo",
|
|
responses(
|
|
(status = 200, description = "Ok"),
|
|
),
|
|
security(("token_jwt" = [])),
|
|
tag = "v1/debug",
|
|
)]
|
|
pub async fn debug_ipinfo(
|
|
State(_state): State<ServerState>,
|
|
TrustedClientIp(ip_addr): TrustedClientIp,
|
|
) -> Result<Json<Vec<IpAddr>>, ()> {
|
|
Ok(Json::from(vec![ip_addr]))
|
|
}
|
|
|
|
fn cacheable_routes(state: ServerState) -> Router<ServerState> {
|
|
Router::new()
|
|
.route(
|
|
"/v1/person/:id/_radius/_token",
|
|
get(person_id_radius_token_get),
|
|
)
|
|
.route("/v1/account/:id/_unix/_token", get(account_id_unix_token))
|
|
.route(
|
|
"/v1/account/:id/_radius/_token",
|
|
get(account_id_radius_token_get),
|
|
)
|
|
.layer(from_fn(cache_me))
|
|
.with_state(state)
|
|
}
|
|
|
|
#[instrument(skip(state))]
|
|
pub(crate) fn route_setup(state: ServerState) -> Router<ServerState> {
|
|
Router::new()
|
|
.route("/v1/oauth2", get(super::v1_oauth2::oauth2_get))
|
|
.route(
|
|
"/v1/oauth2/_basic",
|
|
post(super::v1_oauth2::oauth2_basic_post),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/_public",
|
|
post(super::v1_oauth2::oauth2_public_post),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name",
|
|
get(super::v1_oauth2::oauth2_id_get)
|
|
.patch(super::v1_oauth2::oauth2_id_patch)
|
|
.delete(super::v1_oauth2::oauth2_id_delete),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_image",
|
|
post(super::v1_oauth2::oauth2_id_image_post)
|
|
.delete(super::v1_oauth2::oauth2_id_image_delete),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_basic_secret",
|
|
get(super::v1_oauth2::oauth2_id_get_basic_secret),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_scopemap/:group",
|
|
post(super::v1_oauth2::oauth2_id_scopemap_post)
|
|
.delete(super::v1_oauth2::oauth2_id_scopemap_delete),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_sup_scopemap/:group",
|
|
post(super::v1_oauth2::oauth2_id_sup_scopemap_post)
|
|
.delete(super::v1_oauth2::oauth2_id_sup_scopemap_delete),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_claimmap/:claim_name/:group",
|
|
post(super::v1_oauth2::oauth2_id_claimmap_post)
|
|
.delete(super::v1_oauth2::oauth2_id_claimmap_delete),
|
|
)
|
|
.route(
|
|
"/v1/oauth2/:rs_name/_claimmap/:claim_name",
|
|
post(super::v1_oauth2::oauth2_id_claimmap_join_post),
|
|
)
|
|
.route("/v1/raw/create", post(raw_create))
|
|
.route("/v1/raw/modify", post(raw_modify))
|
|
.route("/v1/raw/delete", post(raw_delete))
|
|
.route("/v1/raw/search", post(raw_search))
|
|
.route("/v1/schema", get(schema_get))
|
|
.route(
|
|
"/v1/schema/attributetype",
|
|
get(schema_attributetype_get), // post(|| async { "TODO" })
|
|
)
|
|
.route(
|
|
"/v1/schema/attributetype/:id",
|
|
get(schema_attributetype_get_id),
|
|
)
|
|
// .route("/schema/attributetype/:id", put(|| async { "TODO" }).patch(|| async { "TODO" }))
|
|
.route(
|
|
"/v1/schema/classtype",
|
|
get(schema_classtype_get), // .post(|| async { "TODO" })
|
|
)
|
|
.route(
|
|
"/v1/schema/classtype/:id",
|
|
get(schema_classtype_get_id), // .put(|| async { "TODO" })
|
|
// .patch(|| async { "TODO" }),
|
|
)
|
|
.route("/v1/self", get(whoami))
|
|
.route("/v1/self/_uat", get(whoami_uat))
|
|
// .route("/v1/self/_attr/:attr", get(|| async { "TODO" }))
|
|
// .route("/v1/self/_credential", get(|| async { "TODO" }))
|
|
// .route("/v1/self/_credential/:cid/_lock", get(|| async { "TODO" }))
|
|
// .route(
|
|
// "/v1/self/_radius",
|
|
// get(|| async { "TODO" })
|
|
// .delete(|| async { "TODO" })
|
|
// .post(|| async { "TODO" }),
|
|
// )
|
|
// .route("/v1/self/_radius/_config", post(|| async { "TODO" }))
|
|
// .route("/v1/self/_radius/_config/:token", get(|| async { "TODO" }))
|
|
// .route(
|
|
// "/v1/self/_radius/_config/:token/apple",
|
|
// get(|| async { "TODO" }),
|
|
// )
|
|
// Applinks are the list of apps this account can access.
|
|
.route("/v1/self/_applinks", get(applinks_get))
|
|
// Person routes
|
|
.route("/v1/person", get(person_get).post(person_post))
|
|
.route(
|
|
"/v1/person/:id",
|
|
get(person_id_get)
|
|
.patch(person_id_patch)
|
|
.delete(person_id_delete),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_attr/:attr",
|
|
get(person_id_get_attr)
|
|
.put(person_id_put_attr)
|
|
.post(person_id_post_attr)
|
|
.delete(person_id_delete_attr),
|
|
)
|
|
// .route("/v1/person/:id/_lock", get(|| async { "TODO" }))
|
|
// .route("/v1/person/:id/_credential", get(|| async { "TODO" }))
|
|
.route(
|
|
"/v1/person/:id/_credential/_status",
|
|
get(person_get_id_credential_status),
|
|
)
|
|
// .route(
|
|
// "/v1/person/:id/_credential/:cid/_lock",
|
|
// get(|| async { "TODO" }),
|
|
// )
|
|
.route(
|
|
"/v1/person/:id/_credential/_update",
|
|
get(person_id_credential_update_get),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_credential/_update_intent/:ttl",
|
|
get(person_id_credential_update_intent_ttl_get),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_credential/_update_intent",
|
|
get(person_id_credential_update_intent_get),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_ssh_pubkeys",
|
|
get(person_id_ssh_pubkeys_get).post(person_id_ssh_pubkeys_post),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_ssh_pubkeys/:tag",
|
|
get(person_id_ssh_pubkeys_tag_get).delete(person_id_ssh_pubkeys_tag_delete),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_radius",
|
|
get(person_id_radius_get)
|
|
.post(person_id_radius_post)
|
|
.delete(person_id_radius_delete),
|
|
)
|
|
.route("/v1/person/:id/_unix", post(service_account_id_unix_post))
|
|
.route(
|
|
"/v1/person/:id/_unix/_credential",
|
|
put(person_id_unix_credential_put).delete(person_id_unix_credential_delete),
|
|
)
|
|
.route(
|
|
"/v1/person/:id/_identify_user",
|
|
post(person_identify_user_post),
|
|
)
|
|
// Service accounts
|
|
.route(
|
|
"/v1/service_account",
|
|
get(service_account_get).post(service_account_post),
|
|
)
|
|
.route(
|
|
"/v1/service_account/",
|
|
get(service_account_get).post(service_account_post),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id",
|
|
get(service_account_id_get)
|
|
.delete(service_account_id_delete)
|
|
.patch(service_account_id_patch),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_attr/:attr",
|
|
get(service_account_id_get_attr)
|
|
.put(service_account_id_put_attr)
|
|
.post(service_account_id_post_attr)
|
|
.delete(service_account_id_delete_attr),
|
|
)
|
|
// .route("/v1/service_account/:id/_lock", get(|| async { "TODO" }))
|
|
.route(
|
|
"/v1/service_account/:id/_into_person",
|
|
#[allow(deprecated)]
|
|
post(service_account_into_person),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_api_token",
|
|
post(service_account_api_token_post).get(service_account_api_token_get),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_api_token/:token_id",
|
|
delete(service_account_api_token_delete),
|
|
)
|
|
// .route(
|
|
// "/v1/service_account/:id/_credential",
|
|
// get(|| async { "TODO" }),
|
|
// )
|
|
.route(
|
|
"/v1/service_account/:id/_credential/_generate",
|
|
get(service_account_credential_generate),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_credential/_status",
|
|
get(service_account_id_credential_status_get),
|
|
)
|
|
// .route(
|
|
// "/v1/service_account/:id/_credential/:cid/_lock",
|
|
// get(|| async { "TODO" }),
|
|
// )
|
|
.route(
|
|
"/v1/service_account/:id/_ssh_pubkeys",
|
|
get(service_account_id_ssh_pubkeys_get).post(service_account_id_ssh_pubkeys_post),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_ssh_pubkeys/:tag",
|
|
get(service_account_id_ssh_pubkeys_tag_get)
|
|
.delete(service_account_id_ssh_pubkeys_tag_delete),
|
|
)
|
|
.route(
|
|
"/v1/service_account/:id/_unix",
|
|
post(service_account_id_unix_post),
|
|
)
|
|
.route(
|
|
"/v1/account/:id/_unix/_auth",
|
|
post(account_id_unix_auth_post),
|
|
)
|
|
.route("/v1/account/:id/_unix/_token", post(account_id_unix_token))
|
|
.route(
|
|
"/v1/account/:id/_radius/_token",
|
|
post(account_id_radius_token_post),
|
|
)
|
|
.route(
|
|
"/v1/account/:id/_ssh_pubkeys",
|
|
#[allow(deprecated)]
|
|
get(account_id_ssh_pubkeys_get),
|
|
)
|
|
.route(
|
|
"/v1/account/:id/_ssh_pubkeys/:tag",
|
|
get(account_id_ssh_pubkeys_tag_get),
|
|
)
|
|
.route(
|
|
"/v1/account/:id/_user_auth_token",
|
|
get(account_id_user_auth_token_get),
|
|
)
|
|
.route(
|
|
"/v1/account/:id/_user_auth_token/:token_id",
|
|
delete(account_user_auth_token_delete),
|
|
)
|
|
.route(
|
|
"/v1/credential/_exchange_intent",
|
|
post(credential_update_exchange_intent),
|
|
)
|
|
.route("/v1/credential/_status", post(credential_update_status))
|
|
.route("/v1/credential/_update", post(credential_update_update))
|
|
.route("/v1/credential/_commit", post(credential_update_commit))
|
|
.route("/v1/credential/_cancel", post(credential_update_cancel))
|
|
// domain-things
|
|
.route("/v1/domain", get(domain_get))
|
|
.route(
|
|
"/v1/domain/_attr/:attr",
|
|
get(domain_attr_get)
|
|
.put(domain_attr_put)
|
|
.delete(domain_attr_delete),
|
|
)
|
|
.route("/v1/group/:id/_unix/_token", get(group_id_unix_token_get))
|
|
.route("/v1/group/:id/_unix", post(group_id_unix_post))
|
|
.route("/v1/group", get(group_get).post(group_post))
|
|
.route("/v1/group/:id", get(group_id_get).delete(group_id_delete))
|
|
.route(
|
|
"/v1/group/:id/_attr/:attr",
|
|
delete(group_id_attr_delete)
|
|
.get(group_id_attr_get)
|
|
.put(group_id_attr_put)
|
|
.post(group_id_attr_post),
|
|
)
|
|
.with_state(state.clone())
|
|
.route("/v1/system", get(system_get))
|
|
.route(
|
|
"/v1/system/_attr/:attr",
|
|
get(system_attr_get)
|
|
.post(system_attr_post)
|
|
.put(system_attr_put)
|
|
.delete(system_attr_delete),
|
|
)
|
|
.route("/v1/recycle_bin", get(recycle_bin_get))
|
|
.route("/v1/recycle_bin/:id", get(recycle_bin_id_get))
|
|
.route(
|
|
"/v1/recycle_bin/:id/_revive",
|
|
post(recycle_bin_revive_id_post),
|
|
)
|
|
// .route("/v1/access_profile", get(|| async { "TODO" }))
|
|
// .route("/v1/access_profile/:id", get(|| async { "TODO" }))
|
|
// .route(
|
|
// "/v1/access_profile/:id/_attr/:attr",
|
|
// get(|| async { "TODO" }),
|
|
// )
|
|
.route("/v1/auth", post(auth))
|
|
.route(V1_AUTH_VALID, get(auth_valid))
|
|
.route("/v1/logout", get(logout))
|
|
.route("/v1/reauth", post(reauth))
|
|
.with_state(state.clone())
|
|
.layer(from_fn(dont_cache_me))
|
|
.merge(cacheable_routes(state))
|
|
.route("/v1/debug/ipinfo", get(debug_ipinfo))
|
|
}
|