mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Are we JSON yet? Kinda. But we're closer. (#1967)
This commit is contained in:
parent
c24d214463
commit
cc79f7eba1
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2439,6 +2439,7 @@ dependencies = [
|
||||||
"kanidmd_lib",
|
"kanidmd_lib",
|
||||||
"oauth2",
|
"oauth2",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sketching",
|
"sketching",
|
||||||
"testkit-macros",
|
"testkit-macros",
|
||||||
|
|
|
@ -24,6 +24,7 @@ use std::os::unix::fs::MetadataExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
use kanidm_proto::v1::*;
|
use kanidm_proto::v1::*;
|
||||||
use reqwest::header::CONTENT_TYPE;
|
use reqwest::header::CONTENT_TYPE;
|
||||||
pub use reqwest::StatusCode;
|
pub use reqwest::StatusCode;
|
||||||
|
@ -44,7 +45,6 @@ mod service_account;
|
||||||
mod sync_account;
|
mod sync_account;
|
||||||
mod system;
|
mod system;
|
||||||
|
|
||||||
pub const APPLICATION_JSON: &str = "application/json";
|
|
||||||
pub const KOPID: &str = "X-KANIDM-OPID";
|
pub const KOPID: &str = "X-KANIDM-OPID";
|
||||||
pub const KSESSIONID: &str = "X-KANIDM-AUTH-SESSION-ID";
|
pub const KSESSIONID: &str = "X-KANIDM-AUTH-SESSION-ID";
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ impl KanidmClient {
|
||||||
.map_err(|e| ClientError::JsonDecode(e, opid))
|
.map_err(|e| ClientError::JsonDecode(e, opid))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn perform_post_request<R: Serialize, T: DeserializeOwned>(
|
pub async fn perform_post_request<R: Serialize, T: DeserializeOwned>(
|
||||||
&self,
|
&self,
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/// Because consistency is great!
|
/// Because consistency is great!
|
||||||
|
|
||||||
|
pub const APPLICATION_JSON: &str = "application/json";
|
||||||
|
|
||||||
/// The "system" path for Kanidm client config
|
/// The "system" path for Kanidm client config
|
||||||
pub const DEFAULT_CLIENT_CONFIG_PATH: &str = "/etc/kanidm/config";
|
pub const DEFAULT_CLIENT_CONFIG_PATH: &str = "/etc/kanidm/config";
|
||||||
/// The user-owned path for Kanidm client config
|
/// The user-owned path for Kanidm client config
|
||||||
|
|
|
@ -341,7 +341,7 @@ pub struct OidcDiscoveryResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||||
pub struct ErrorResponse {
|
pub struct ErrorResponse {
|
||||||
pub error: String,
|
pub error: String,
|
||||||
pub error_description: Option<String>,
|
pub error_description: Option<String>,
|
||||||
|
|
|
@ -611,8 +611,12 @@ impl fmt::Display for UnixUserToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct AccountUnixExtend {
|
pub struct AccountUnixExtend {
|
||||||
pub gidnumber: Option<u32>,
|
pub gidnumber: Option<u32>,
|
||||||
|
// TODO: rename shell to loginshell everywhere we can find
|
||||||
|
/// The internal attribute is "loginshell" but we use shell in the API currently
|
||||||
|
#[serde(alias = "loginshell")]
|
||||||
pub shell: Option<String>,
|
pub shell: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::Extension;
|
use axum::Extension;
|
||||||
|
use http::header::CONTENT_TYPE;
|
||||||
use http::HeaderValue;
|
use http::HeaderValue;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
|
@ -163,7 +164,7 @@ pub(crate) async fn manifest(
|
||||||
let mut res = Response::new(manifest_string);
|
let mut res = Response::new(manifest_string);
|
||||||
|
|
||||||
res.headers_mut()
|
res.headers_mut()
|
||||||
.insert("Content-Type", HeaderValue::from_static(MIME_TYPE_MANIFEST));
|
.insert(CONTENT_TYPE, HeaderValue::from_static(MIME_TYPE_MANIFEST));
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ pub async fn strict_transport_security_layer<B>(request: Request<B>, next: Next<
|
||||||
let mut response = next.run(request).await;
|
let mut response = next.run(request).await;
|
||||||
|
|
||||||
// add the header
|
// add the header
|
||||||
let headers = response.headers_mut();
|
response.headers_mut().insert(
|
||||||
let hsts_header = HeaderValue::from_static(HSTS_HEADER);
|
http::header::STRICT_TRANSPORT_SECURITY,
|
||||||
|
HeaderValue::from_static(HSTS_HEADER),
|
||||||
headers.insert(http::header::STRICT_TRANSPORT_SECURITY, hsts_header);
|
);
|
||||||
|
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ use axum::{
|
||||||
response::Response,
|
response::Response,
|
||||||
TypedHeader,
|
TypedHeader,
|
||||||
};
|
};
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use http::header::CONTENT_TYPE;
|
||||||
use http::HeaderValue;
|
use http::HeaderValue;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -19,8 +21,9 @@ const KANIDM_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
/// Injects a header into the response with "X-KANIDM-VERSION" matching the version of the package.
|
/// Injects a header into the response with "X-KANIDM-VERSION" matching the version of the package.
|
||||||
pub async fn version_middleware<B>(request: Request<B>, next: Next<B>) -> Response {
|
pub async fn version_middleware<B>(request: Request<B>, next: Next<B>) -> Response {
|
||||||
let mut response = next.run(request).await;
|
let mut response = next.run(request).await;
|
||||||
let headers = response.headers_mut();
|
response
|
||||||
headers.insert("X-KANIDM-VERSION", HeaderValue::from_static(KANIDM_VERSION));
|
.headers_mut()
|
||||||
|
.insert("X-KANIDM-VERSION", HeaderValue::from_static(KANIDM_VERSION));
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +34,41 @@ pub struct KOpId {
|
||||||
pub uat: Option<String>,
|
pub uat: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure the status code is 200..=299
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
fn from_200_to_299(status: http::StatusCode) -> bool {
|
||||||
|
status.as_u16() >= 200 && status.as_u16() <= 299
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_200_to_299() {
|
||||||
|
assert!(from_200_to_299(http::StatusCode::OK));
|
||||||
|
assert!(from_200_to_299(http::StatusCode::IM_USED));
|
||||||
|
assert!(!from_200_to_299(http::StatusCode::BAD_REQUEST));
|
||||||
|
assert!(!from_200_to_299(http::StatusCode::INTERNAL_SERVER_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
/// This is a debug middleware to ensure that /v1/ endpoints only return JSON
|
||||||
|
#[instrument(name = "are_we_json_yet", skip_all)]
|
||||||
|
pub async fn are_we_json_yet<B>(request: Request<B>, next: Next<B>) -> Response {
|
||||||
|
let uri = request.uri().path().to_string();
|
||||||
|
|
||||||
|
let response = next.run(request).await;
|
||||||
|
|
||||||
|
if uri.starts_with("/v1") && from_200_to_299(response.status()) {
|
||||||
|
let headers = response.headers();
|
||||||
|
assert!(headers.contains_key(CONTENT_TYPE));
|
||||||
|
dbg!(headers.get(CONTENT_TYPE));
|
||||||
|
assert!(
|
||||||
|
headers.get(CONTENT_TYPE)
|
||||||
|
== Some(&HeaderValue::from_static(crate::https::APPLICATION_JSON))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
/// This runs at the start of the request, adding an extension with `KOpId` which has useful things inside it.
|
/// This runs at the start of the request, adding an extension with `KOpId` which has useful things inside it.
|
||||||
#[instrument(name = "request", skip_all)]
|
#[instrument(name = "request", skip_all)]
|
||||||
pub async fn kopid_middleware<B>(
|
pub async fn kopid_middleware<B>(
|
||||||
|
|
|
@ -26,32 +26,26 @@ pub async fn security_headers_layer<B>(
|
||||||
//
|
//
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||||
// https://scotthelme.co.uk/hardening-your-http-response-headers/#x-content-type-options
|
// https://scotthelme.co.uk/hardening-your-http-response-headers/#x-content-type-options
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
headers.insert(
|
headers.insert(
|
||||||
X_CONTENT_TYPE_OPTIONS,
|
X_CONTENT_TYPE_OPTIONS,
|
||||||
HeaderValue::from_str(X_CONTENT_TYPE_OPTIONS_VALUE)
|
HeaderValue::from_static(X_CONTENT_TYPE_OPTIONS_VALUE),
|
||||||
.expect("Failed to generate security header X-Content-Type-Options"),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Permissions policy defines access to platform services like geolocation, fullscreen etc.
|
// Permissions policy defines access to platform services like geolocation, fullscreen etc.
|
||||||
//
|
//
|
||||||
// https://www.w3.org/TR/permissions-policy-1/
|
// https://www.w3.org/TR/permissions-policy-1/
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
headers.insert(
|
headers.insert(
|
||||||
"Permissions-Policy",
|
"Permissions-Policy",
|
||||||
HeaderValue::from_str(PERMISSIONS_POLICY_VALUE)
|
HeaderValue::from_static(PERMISSIONS_POLICY_VALUE),
|
||||||
.expect("Failed to generate security header Permissions-Policy"),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Don't send a referrer header when the user is navigating to a non-HTTPS URL
|
// Don't send a referrer header when the user is navigating to a non-HTTPS URL
|
||||||
// Ref:
|
// Ref:
|
||||||
// https://scotthelme.co.uk/a-new-security-header-referrer-policy/
|
// https://scotthelme.co.uk/a-new-security-header-referrer-policy/
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
headers.insert(
|
headers.insert(
|
||||||
http::header::REFERRER_POLICY,
|
http::header::REFERRER_POLICY,
|
||||||
HeaderValue::from_str("no-referrer-when-downgrade")
|
HeaderValue::from_static("no-referrer-when-downgrade"),
|
||||||
.expect("Failed to generate Referer-Policy header"),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
response
|
response
|
||||||
|
|
|
@ -14,21 +14,24 @@ use crate::actors::v1_write::QueryServerWriteV1;
|
||||||
use crate::config::{Configuration, ServerRole, TlsConfiguration};
|
use crate::config::{Configuration, ServerRole, TlsConfiguration};
|
||||||
use axum::extract::connect_info::{IntoMakeServiceWithConnectInfo, ResponseFuture};
|
use axum::extract::connect_info::{IntoMakeServiceWithConnectInfo, ResponseFuture};
|
||||||
use axum::middleware::{from_fn, from_fn_with_state};
|
use axum::middleware::{from_fn, from_fn_with_state};
|
||||||
use axum::response::{Redirect, Response};
|
use axum::response::{IntoResponse, Redirect, Response};
|
||||||
use axum::routing::*;
|
use axum::routing::*;
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use axum_csp::{CspDirectiveType, CspValue};
|
use axum_csp::{CspDirectiveType, CspValue};
|
||||||
use axum_macros::FromRef;
|
use axum_macros::FromRef;
|
||||||
use compact_jwt::{Jws, JwsSigner, JwsUnverified};
|
use compact_jwt::{Jws, JwsSigner, JwsUnverified};
|
||||||
use generic::*;
|
use generic::*;
|
||||||
use http::{HeaderMap, HeaderValue};
|
use http::header::{ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE};
|
||||||
|
use http::{HeaderMap, HeaderValue, StatusCode};
|
||||||
use hyper::server::accept::Accept;
|
use hyper::server::accept::Accept;
|
||||||
use hyper::server::conn::{AddrStream, Http};
|
use hyper::server::conn::{AddrStream, Http};
|
||||||
use hyper::Body;
|
use hyper::Body;
|
||||||
use javascript::*;
|
use javascript::*;
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
use kanidm_proto::v1::OperationError;
|
use kanidm_proto::v1::OperationError;
|
||||||
use kanidmd_lib::status::StatusActor;
|
use kanidmd_lib::status::StatusActor;
|
||||||
use openssl::ssl::{Ssl, SslAcceptor, SslFiletype, SslMethod};
|
use openssl::ssl::{Ssl, SslAcceptor, SslFiletype, SslMethod};
|
||||||
|
use sketching::*;
|
||||||
use tokio_openssl::SslStream;
|
use tokio_openssl::SslStream;
|
||||||
|
|
||||||
use futures_util::future::poll_fn;
|
use futures_util::future::poll_fn;
|
||||||
|
@ -247,7 +250,13 @@ pub async fn create_https_server(
|
||||||
// This is because the last middleware here is the first to be entered and the last
|
// This is because the last middleware here is the first to be entered and the last
|
||||||
// to be exited, and this middleware sets up ids' and other bits for for logging
|
// to be exited, and this middleware sets up ids' and other bits for for logging
|
||||||
// coherence to be maintained.
|
// coherence to be maintained.
|
||||||
.layer(from_fn(middleware::kopid_middleware))
|
.layer(from_fn(middleware::kopid_middleware));
|
||||||
|
|
||||||
|
// layer which checks the responses have a content-type of JSON when we're in debug mode
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let app = app.layer(from_fn(middleware::are_we_json_yet));
|
||||||
|
|
||||||
|
let app = app
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
// the connect_info bit here lets us pick up the remote address of the client
|
// the connect_info bit here lets us pick up the remote address of the client
|
||||||
.into_make_service_with_connect_info::<SocketAddr>();
|
.into_make_service_with_connect_info::<SocketAddr>();
|
||||||
|
@ -369,8 +378,8 @@ async fn handle_conn(
|
||||||
std::io::Error::from(ErrorKind::ConnectionAborted)
|
std::io::Error::from(ErrorKind::ConnectionAborted)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(_error) => {
|
Err(error) => {
|
||||||
// trace!("Failed to handle connection: {:?}", error);
|
trace!("Failed to handle connection: {:?}", error);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -393,7 +402,10 @@ pub fn to_axum_response<T: Serialize + core::fmt::Debug>(
|
||||||
};
|
};
|
||||||
trace!("Response Body: {:?}", body);
|
trace!("Response Body: {:?}", body);
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder().body(Body::from(body)).unwrap()
|
Response::builder()
|
||||||
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
|
.body(Body::from(body))
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("OperationError: {:?}", e);
|
debug!("OperationError: {:?}", e);
|
||||||
|
@ -430,3 +442,27 @@ pub fn to_axum_response<T: Serialize + core::fmt::Debug>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper for the externally-defined error type from the protocol
|
||||||
|
pub struct HttpOperationError(OperationError);
|
||||||
|
|
||||||
|
impl IntoResponse for HttpOperationError {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
let HttpOperationError(error) = self;
|
||||||
|
|
||||||
|
let body = match serde_json::to_string(&error) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(e) => {
|
||||||
|
admin_warn!("Failed to serialize error response: original_error=\"{:?}\" serialization_error=\"{:?}\"", error , e);
|
||||||
|
format!("{:?}", error)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::BAD_REQUEST)
|
||||||
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
|
.body(Body::from(body))
|
||||||
|
.unwrap()
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
use super::middleware::KOpId;
|
use super::middleware::KOpId;
|
||||||
use super::v1::{json_rest_event_get, json_rest_event_post};
|
use super::v1::{json_rest_event_get, json_rest_event_post};
|
||||||
use super::{to_axum_response, ServerState};
|
use super::{to_axum_response, HttpOperationError, ServerState};
|
||||||
use axum::extract::{Path, Query, State};
|
use axum::extract::{Path, Query, State};
|
||||||
use axum::middleware::from_fn;
|
use axum::middleware::from_fn;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{Extension, Form, Json, Router};
|
use axum::{Extension, Form, Json, Router};
|
||||||
|
use axum_macros::debug_handler;
|
||||||
use http::header::{
|
use http::header::{
|
||||||
ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, AUTHORIZATION, LOCATION,
|
ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, AUTHORIZATION, CONTENT_TYPE,
|
||||||
|
LOCATION, WWW_AUTHENTICATE,
|
||||||
};
|
};
|
||||||
use http::{HeaderMap, HeaderValue, StatusCode};
|
use http::{HeaderMap, HeaderValue, StatusCode};
|
||||||
use hyper::Body;
|
use hyper::Body;
|
||||||
use kanidm_proto::oauth2::AuthorisationResponse;
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
|
use kanidm_proto::oauth2::{AuthorisationResponse, OidcDiscoveryResponse};
|
||||||
use kanidm_proto::v1::Entry as ProtoEntry;
|
use kanidm_proto::v1::Entry as ProtoEntry;
|
||||||
use kanidmd_lib::idm::oauth2::{
|
use kanidmd_lib::idm::oauth2::{
|
||||||
AccessTokenIntrospectRequest, AccessTokenRequest, AuthorisationRequest, AuthorisePermitSuccess,
|
AccessTokenIntrospectRequest, AccessTokenRequest, AuthorisationRequest, AuthorisePermitSuccess,
|
||||||
|
@ -22,6 +25,45 @@ use kanidmd_lib::prelude::*;
|
||||||
use kanidmd_lib::value::PartialValue;
|
use kanidmd_lib::value::PartialValue;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub struct HTTPOauth2Error(Oauth2Error);
|
||||||
|
|
||||||
|
impl IntoResponse for HTTPOauth2Error {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
let HTTPOauth2Error(error) = self;
|
||||||
|
|
||||||
|
if let Oauth2Error::AuthenticationRequired = error {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
|
.header(WWW_AUTHENTICATE, "Bearer")
|
||||||
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap()
|
||||||
|
} else {
|
||||||
|
let err = ErrorResponse {
|
||||||
|
error: error.to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let body = match serde_json::to_string(&err) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(e) => {
|
||||||
|
admin_warn!("Failed to serialize error response: original_error=\"{:?}\" serialization_error=\"{:?}\"", err, e);
|
||||||
|
format!("{:?}", err)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::BAD_REQUEST)
|
||||||
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
|
.body(Body::from(body))
|
||||||
|
.unwrap()
|
||||||
|
|
||||||
|
}
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// == Oauth2 Configuration Endpoints ==
|
// == Oauth2 Configuration Endpoints ==
|
||||||
|
|
||||||
/// List all the OAuth2 Resource Servers
|
/// List all the OAuth2 Resource Servers
|
||||||
|
@ -73,7 +115,7 @@ pub async fn oauth2_id_get(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(rs_name): Path<String>,
|
Path(rs_name): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
|
|
||||||
let res = state
|
let res = state
|
||||||
|
@ -89,7 +131,7 @@ pub async fn oauth2_id_get_basic_secret(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path(rs_name): Path<String>,
|
Path(rs_name): Path<String>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_r_ref
|
.qe_r_ref
|
||||||
|
@ -103,7 +145,7 @@ pub async fn oauth2_id_patch(
|
||||||
Path(rs_name): Path<String>,
|
Path(rs_name): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Json(obj): Json<ProtoEntry>,
|
Json(obj): Json<ProtoEntry>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
|
|
||||||
let res = state
|
let res = state
|
||||||
|
@ -118,7 +160,7 @@ pub async fn oauth2_id_scopemap_post(
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path((rs_name, group)): Path<(String, String)>,
|
Path((rs_name, group)): Path<(String, String)>,
|
||||||
Json(scopes): Json<Vec<String>>,
|
Json(scopes): Json<Vec<String>>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
|
@ -131,7 +173,7 @@ pub async fn oauth2_id_scopemap_delete(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path((rs_name, group)): Path<(String, String)>,
|
Path((rs_name, group)): Path<(String, String)>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
|
@ -145,7 +187,7 @@ pub async fn oauth2_id_sup_scopemap_post(
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path((rs_name, group)): Path<(String, String)>,
|
Path((rs_name, group)): Path<(String, String)>,
|
||||||
Json(scopes): Json<Vec<String>>,
|
Json(scopes): Json<Vec<String>>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
|
@ -158,7 +200,7 @@ pub async fn oauth2_id_sup_scopemap_delete(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path((rs_name, group)): Path<(String, String)>,
|
Path((rs_name, group)): Path<(String, String)>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
|
@ -171,7 +213,7 @@ pub async fn oauth2_id_delete(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path(rs_name): Path<String>,
|
Path(rs_name): Path<String>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let filter = oauth2_id(&rs_name);
|
let filter = oauth2_id(&rs_name);
|
||||||
let res = state
|
let res = state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
|
@ -337,7 +379,7 @@ async fn oauth2_authorise(
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::UNAUTHORIZED)
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
.header("WWW-Authenticate", HeaderValue::from_str("Bearer").unwrap())
|
.header(WWW_AUTHENTICATE, HeaderValue::from_static("Bearer"))
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -432,9 +474,9 @@ async fn oauth2_authorise_permit(
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::FOUND)
|
.status(StatusCode::FOUND)
|
||||||
.header("Location", redirect_uri.as_str())
|
.header(LOCATION, redirect_uri.as_str())
|
||||||
.header(
|
.header(
|
||||||
"Access-Control-Allow-Origin",
|
ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||||
redirect_uri.origin().ascii_serialization(),
|
redirect_uri.origin().ascii_serialization(),
|
||||||
)
|
)
|
||||||
.body(Body::empty())
|
.body(Body::empty())
|
||||||
|
@ -464,7 +506,7 @@ pub async fn oauth2_authorise_reject_post(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Form(consent_req): Form<ConsentRequestData>,
|
Form(consent_req): Form<ConsentRequestData>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
oauth2_authorise_reject(state, consent_req.token, kopid).await
|
oauth2_authorise_reject(state, consent_req.token, kopid).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +514,7 @@ pub async fn oauth2_authorise_reject_get(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Query(consent_req): Query<ConsentRequestData>,
|
Query(consent_req): Query<ConsentRequestData>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
oauth2_authorise_reject(state, consent_req.token, kopid).await
|
oauth2_authorise_reject(state, consent_req.token, kopid).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +525,7 @@ async fn oauth2_authorise_reject(
|
||||||
state: ServerState,
|
state: ServerState,
|
||||||
consent_req: String,
|
consent_req: String,
|
||||||
kopid: KOpId,
|
kopid: KOpId,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
// Need to go back to the redir_uri
|
// Need to go back to the redir_uri
|
||||||
// For this, we'll need to lookup where to go.
|
// For this, we'll need to lookup where to go.
|
||||||
|
|
||||||
|
@ -525,12 +567,14 @@ async fn oauth2_authorise_reject(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[axum_macros::debug_handler]
|
||||||
|
#[instrument(skip(state, kopid, headers), level = "DEBUG")]
|
||||||
pub async fn oauth2_token_post(
|
pub async fn oauth2_token_post(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
headers: HeaderMap, // TODO: make this a typed basic auth header
|
headers: HeaderMap,
|
||||||
Form(tok_req): Form<AccessTokenRequest>,
|
Form(tok_req): Form<AccessTokenRequest>,
|
||||||
) -> impl IntoResponse {
|
) -> Result<Json<kanidm_proto::oauth2::AccessTokenResponse>, HTTPOauth2Error> {
|
||||||
// This is called directly by the resource server, where we then issue
|
// This is called directly by the resource server, where we then issue
|
||||||
// the token to the caller.
|
// the token to the caller.
|
||||||
|
|
||||||
|
@ -545,53 +589,13 @@ pub async fn oauth2_token_post(
|
||||||
// grant? Should we cease the delayed/async session update here and just opt
|
// grant? Should we cease the delayed/async session update here and just opt
|
||||||
// for a wr txn?
|
// for a wr txn?
|
||||||
|
|
||||||
let res = state
|
match state
|
||||||
.qe_w_ref
|
.qe_w_ref
|
||||||
.handle_oauth2_token_exchange(client_authz, tok_req, kopid.eventid)
|
.handle_oauth2_token_exchange(client_authz, tok_req, kopid.eventid)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
match res {
|
Ok(tok_res) => Ok(Json(tok_res)),
|
||||||
Ok(atr) =>
|
Err(e) => Err(HTTPOauth2Error(e)),
|
||||||
{
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::OK)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(serde_json::to_string(&atr).unwrap()))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
Err(Oauth2Error::AuthenticationRequired) =>
|
|
||||||
{
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::UNAUTHORIZED)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::empty())
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
|
||||||
let err = ErrorResponse {
|
|
||||||
error: e.to_string(),
|
|
||||||
error_description: None,
|
|
||||||
error_uri: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let body = match serde_json::to_string(&err) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(e) => {
|
|
||||||
admin_warn!("Failed to serialize error response: original_error=\"{:?}\" serialization_error=\"{:?}\"", err, e);
|
|
||||||
format!("{:?}", err)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::BAD_REQUEST)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(body))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +604,7 @@ pub async fn oauth2_openid_discovery_get(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(client_id): Path<String>,
|
Path(client_id): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
) -> impl IntoResponse {
|
) -> Result<Json<OidcDiscoveryResponse>, HttpOperationError> {
|
||||||
// let client_id = req.get_url_param("client_id")?;
|
// let client_id = req.get_url_param("client_id")?;
|
||||||
|
|
||||||
let res = state
|
let res = state
|
||||||
|
@ -609,51 +613,26 @@ pub async fn oauth2_openid_discovery_get(
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(dsc) => {
|
Ok(dsc) => Ok(Json(dsc)),
|
||||||
// Humans may look at this so we pretty it.
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
let body = serde_json::to_string_pretty(&dsc).unwrap();
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::OK)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(body))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(err = ?e, "Unable to access discovery info");
|
error!(err = ?e, "Unable to access discovery info");
|
||||||
let body = match serde_json::to_string(&e) {
|
Err(HttpOperationError(e))
|
||||||
Ok(val) => val,
|
|
||||||
Err(e) => {
|
|
||||||
format!("{:?}", e)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::BAD_REQUEST)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(body))
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
pub async fn oauth2_openid_userinfo_get(
|
pub async fn oauth2_openid_userinfo_get(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(client_id): Path<String>,
|
Path(client_id): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
) -> Response<Body> {
|
) -> impl IntoResponse {
|
||||||
// The token we want to inspect is in the authorisation header.
|
// The token we want to inspect is in the authorisation header.
|
||||||
let client_token = match kopid.uat {
|
let client_token = match kopid.uat {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
error!("Bearer Authentication Not Provided");
|
error!("Bearer Authentication Not Provided");
|
||||||
#[allow(clippy::unwrap_used)]
|
return Err(HTTPOauth2Error(Oauth2Error::AuthenticationRequired));
|
||||||
return Response::builder()
|
|
||||||
.status(StatusCode::UNAUTHORIZED)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from("Invalid Bearer Authorisation"))
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -663,36 +642,8 @@ pub async fn oauth2_openid_userinfo_get(
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(uir) => {
|
Ok(uir) => Ok(Json(uir)),
|
||||||
#[allow(clippy::unwrap_used)]
|
Err(e) => Err(HTTPOauth2Error(e)),
|
||||||
let body = serde_json::to_string(&uir).unwrap();
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::OK)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(body))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
let err = ErrorResponse {
|
|
||||||
error: e.to_string(),
|
|
||||||
error_description: None,
|
|
||||||
error_uri: None,
|
|
||||||
};
|
|
||||||
let body = match serde_json::to_string(&err) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(e) => {
|
|
||||||
format!("{:?}", e)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
Response::builder()
|
|
||||||
.status(StatusCode::BAD_REQUEST)
|
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
|
||||||
.body(Body::from(body))
|
|
||||||
.unwrap()
|
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6750#section-6.2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,12 +651,13 @@ pub async fn oauth2_openid_publickey_get(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(client_id): Path<String>,
|
Path(client_id): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
) -> impl IntoResponse {
|
) -> Response<Body> {
|
||||||
let res = state
|
to_axum_response(
|
||||||
.qe_r_ref
|
state
|
||||||
.handle_oauth2_openid_publickey(client_id, kopid.eventid)
|
.qe_r_ref
|
||||||
.await;
|
.handle_oauth2_openid_publickey(client_id, kopid.eventid)
|
||||||
to_axum_response(res)
|
.await,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called directly by the resource server, where we then issue
|
/// This is called directly by the resource server, where we then issue
|
||||||
|
@ -760,6 +712,7 @@ pub async fn oauth2_token_introspect_post(
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.body(Body::from(body))
|
.body(Body::from(body))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -776,8 +729,7 @@ pub async fn oauth2_token_introspect_post(
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
||||||
let err = ErrorResponse {
|
let err = ErrorResponse {
|
||||||
error: e.to_string(),
|
error: e.to_string(),
|
||||||
error_description: None,
|
..Default::default()
|
||||||
error_uri: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = match serde_json::to_string(&err) {
|
let body = match serde_json::to_string(&err) {
|
||||||
|
@ -847,21 +799,22 @@ pub async fn oauth2_token_revoke_post(
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
||||||
let err = ErrorResponse {
|
let err = ErrorResponse {
|
||||||
error: e.to_string(),
|
error: e.to_string(),
|
||||||
error_description: None,
|
..Default::default()
|
||||||
error_uri: None,
|
|
||||||
};
|
};
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::BAD_REQUEST)
|
.status(StatusCode::BAD_REQUEST)
|
||||||
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
.header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
|
||||||
.body(Body::from(serde_json::to_string(&err).unwrap()))
|
.body(Body::from(
|
||||||
|
serde_json::to_string(&err).unwrap_or("".to_string()),
|
||||||
|
))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some requests from browsers require preflight so that CORS works.
|
// Some requests from browsers require preflight so that CORS works.
|
||||||
pub async fn oauth2_preflight_options() -> impl IntoResponse {
|
pub async fn oauth2_preflight_options() -> Response<Body> {
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
|
|
|
@ -2,6 +2,7 @@ use axum::extract::State;
|
||||||
use axum::http::HeaderValue;
|
use axum::http::HeaderValue;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
use axum::Extension;
|
use axum::Extension;
|
||||||
|
use http::header::CONTENT_TYPE;
|
||||||
|
|
||||||
use super::middleware::KOpId;
|
use super::middleware::KOpId;
|
||||||
use super::ServerState;
|
use super::ServerState;
|
||||||
|
@ -58,7 +59,7 @@ pub async fn ui_handler(
|
||||||
|
|
||||||
let mut res = Response::new(body);
|
let mut res = Response::new(body);
|
||||||
res.headers_mut().insert(
|
res.headers_mut().insert(
|
||||||
"Content-Type",
|
CONTENT_TYPE,
|
||||||
HeaderValue::from_static("text/html;charset=utf-8"),
|
HeaderValue::from_static("text/html;charset=utf-8"),
|
||||||
);
|
);
|
||||||
res
|
res
|
||||||
|
|
|
@ -892,6 +892,7 @@ pub async fn account_get_id_radius_token(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Expects an `AccountUnixExtend` object
|
||||||
pub async fn account_post_id_unix(
|
pub async fn account_post_id_unix(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
|
@ -1403,27 +1404,26 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/v1/schema/classtype/:id",
|
"/v1/schema/classtype/:id",
|
||||||
get(schema_classtype_get_id)
|
get(schema_classtype_get_id), // .put(|| async { "TODO" })
|
||||||
.put(|| async { "TODO" })
|
// .patch(|| async { "TODO" }),
|
||||||
.patch(|| async { "TODO" }),
|
|
||||||
)
|
)
|
||||||
.route("/v1/self", get(whoami))
|
.route("/v1/self", get(whoami))
|
||||||
.route("/v1/self/_uat", get(whoami_uat))
|
.route("/v1/self/_uat", get(whoami_uat))
|
||||||
.route("/v1/self/_attr/:attr", get(|| async { "TODO" }))
|
// .route("/v1/self/_attr/:attr", get(|| async { "TODO" }))
|
||||||
.route("/v1/self/_credential", get(|| async { "TODO" }))
|
// .route("/v1/self/_credential", get(|| async { "TODO" }))
|
||||||
.route("/v1/self/_credential/:cid/_lock", get(|| async { "TODO" }))
|
// .route("/v1/self/_credential/:cid/_lock", get(|| async { "TODO" }))
|
||||||
.route(
|
// .route(
|
||||||
"/v1/self/_radius",
|
// "/v1/self/_radius",
|
||||||
get(|| async { "TODO" })
|
// get(|| async { "TODO" })
|
||||||
.delete(|| async { "TODO" })
|
// .delete(|| async { "TODO" })
|
||||||
.post(|| async { "TODO" }),
|
// .post(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
.route("/v1/self/_radius/_config", 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", get(|| async { "TODO" }))
|
||||||
.route(
|
// .route(
|
||||||
"/v1/self/_radius/_config/:token/apple",
|
// "/v1/self/_radius/_config/:token/apple",
|
||||||
get(|| async { "TODO" }),
|
// get(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
// Applinks are the list of apps this account can access.
|
// Applinks are the list of apps this account can access.
|
||||||
.route("/v1/self/_applinks", get(applinks_get))
|
.route("/v1/self/_applinks", get(applinks_get))
|
||||||
// Person routes
|
// Person routes
|
||||||
|
@ -1442,16 +1442,16 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
.post(account_id_post_attr)
|
.post(account_id_post_attr)
|
||||||
.delete(account_id_delete_attr),
|
.delete(account_id_delete_attr),
|
||||||
)
|
)
|
||||||
.route("/v1/person/:id/_lock", get(|| async { "TODO" }))
|
// .route("/v1/person/:id/_lock", get(|| async { "TODO" }))
|
||||||
.route("/v1/person/:id/_credential", get(|| async { "TODO" }))
|
// .route("/v1/person/:id/_credential", get(|| async { "TODO" }))
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_credential/_status",
|
"/v1/person/:id/_credential/_status",
|
||||||
get(account_get_id_credential_status),
|
get(account_get_id_credential_status),
|
||||||
)
|
)
|
||||||
.route(
|
// .route(
|
||||||
"/v1/person/:id/_credential/:cid/_lock",
|
// "/v1/person/:id/_credential/:cid/_lock",
|
||||||
get(|| async { "TODO" }),
|
// get(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_credential/_update",
|
"/v1/person/:id/_credential/_update",
|
||||||
get(account_get_id_credential_update),
|
get(account_get_id_credential_update),
|
||||||
|
@ -1481,7 +1481,7 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_radius/_token",
|
"/v1/person/:id/_radius/_token",
|
||||||
get(account_get_id_radius_token),
|
get(account_get_id_radius_token),
|
||||||
) // TODO: make this cacheable
|
) // TODO: make radius token cacheable
|
||||||
.route("/v1/person/:id/_unix", post(account_post_id_unix))
|
.route("/v1/person/:id/_unix", post(account_post_id_unix))
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_unix/_credential",
|
"/v1/person/:id/_unix/_credential",
|
||||||
|
@ -1507,7 +1507,7 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
.post(account_id_post_attr)
|
.post(account_id_post_attr)
|
||||||
.delete(account_id_delete_attr),
|
.delete(account_id_delete_attr),
|
||||||
)
|
)
|
||||||
.route("/v1/service_account/:id/_lock", get(|| async { "TODO" }))
|
// .route("/v1/service_account/:id/_lock", get(|| async { "TODO" }))
|
||||||
.route(
|
.route(
|
||||||
"/v1/service_account/:id/_into_person",
|
"/v1/service_account/:id/_into_person",
|
||||||
post(service_account_into_person),
|
post(service_account_into_person),
|
||||||
|
@ -1520,10 +1520,10 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
"/v1/service_account/:id/_api_token/:token_id",
|
"/v1/service_account/:id/_api_token/:token_id",
|
||||||
delete(service_account_api_token_delete),
|
delete(service_account_api_token_delete),
|
||||||
)
|
)
|
||||||
.route(
|
// .route(
|
||||||
"/v1/service_account/:id/_credential",
|
// "/v1/service_account/:id/_credential",
|
||||||
get(|| async { "TODO" }),
|
// get(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
.route(
|
.route(
|
||||||
"/v1/service_account/:id/_credential/_generate",
|
"/v1/service_account/:id/_credential/_generate",
|
||||||
get(service_account_credential_generate),
|
get(service_account_credential_generate),
|
||||||
|
@ -1532,10 +1532,10 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
"/v1/service_account/:id/_credential/_status",
|
"/v1/service_account/:id/_credential/_status",
|
||||||
get(account_get_id_credential_status),
|
get(account_get_id_credential_status),
|
||||||
)
|
)
|
||||||
.route(
|
// .route(
|
||||||
"/v1/service_account/:id/_credential/:cid/_lock",
|
// "/v1/service_account/:id/_credential/:cid/_lock",
|
||||||
get(|| async { "TODO" }),
|
// get(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
.route(
|
.route(
|
||||||
"/v1/service_account/:id/_ssh_pubkeys",
|
"/v1/service_account/:id/_ssh_pubkeys",
|
||||||
get(account_get_id_ssh_pubkeys).post(account_post_id_ssh_pubkey),
|
get(account_get_id_ssh_pubkeys).post(account_post_id_ssh_pubkey),
|
||||||
|
@ -1614,12 +1614,12 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
"/v1/recycle_bin/:id/_revive",
|
"/v1/recycle_bin/:id/_revive",
|
||||||
post(recycle_bin_revive_id_post),
|
post(recycle_bin_revive_id_post),
|
||||||
)
|
)
|
||||||
.route("/v1/access_profile", get(|| async { "TODO" }))
|
// .route("/v1/access_profile", get(|| async { "TODO" }))
|
||||||
.route("/v1/access_profile/:id", get(|| async { "TODO" }))
|
// .route("/v1/access_profile/:id", get(|| async { "TODO" }))
|
||||||
.route(
|
// .route(
|
||||||
"/v1/access_profile/:id/_attr/:attr",
|
// "/v1/access_profile/:id/_attr/:attr",
|
||||||
get(|| async { "TODO" }),
|
// get(|| async { "TODO" }),
|
||||||
)
|
// )
|
||||||
.route("/v1/auth", post(auth))
|
.route("/v1/auth", post(auth))
|
||||||
.route("/v1/auth/valid", get(auth_valid))
|
.route("/v1/auth/valid", get(auth_valid))
|
||||||
.route("/v1/logout", get(logout))
|
.route("/v1/logout", get(logout))
|
||||||
|
|
|
@ -28,12 +28,12 @@ kanidmd_lib = { workspace = true }
|
||||||
# used for webdriver testing
|
# used for webdriver testing
|
||||||
hyper-tls = { workspace = true }
|
hyper-tls = { workspace = true }
|
||||||
# used for webdriver testing
|
# used for webdriver testing
|
||||||
fantoccini = { version="0.19.3", optional=true}
|
fantoccini = { version = "0.19.3", optional = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
|
||||||
|
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
reqwest = { workspace = true, default-features = false, features=["cookies"] }
|
reqwest = { workspace = true, default-features = false, features = ["cookies"] }
|
||||||
sketching = { workspace = true }
|
sketching = { workspace = true }
|
||||||
testkit-macros = { workspace = true }
|
testkit-macros = { workspace = true }
|
||||||
tracing = { workspace = true, features = ["attributes"] }
|
tracing = { workspace = true, features = ["attributes"] }
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use kanidm_client::KanidmClient;
|
use kanidm_client::KanidmClient;
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
use kanidmd_testkit::*;
|
use kanidmd_testkit::*;
|
||||||
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
|
||||||
static USER_READABLE_ATTRS: [&str; 9] = [
|
static USER_READABLE_ATTRS: [&str; 9] = [
|
||||||
"name",
|
"name",
|
||||||
|
@ -607,7 +608,7 @@ async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.post(format!("{}/v1/raw/delete", &addr))
|
.post(format!("{}/v1/raw/delete", &addr))
|
||||||
.header("Content-Type", "application/json")
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.body(post_body)
|
.body(post_body)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -4,11 +4,13 @@ use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use compact_jwt::{JwkKeySet, JwsValidator, OidcToken, OidcUnverified};
|
use compact_jwt::{JwkKeySet, JwsValidator, OidcToken, OidcUnverified};
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
use kanidm_proto::oauth2::{
|
use kanidm_proto::oauth2::{
|
||||||
AccessTokenIntrospectRequest, AccessTokenIntrospectResponse, AccessTokenRequest,
|
AccessTokenIntrospectRequest, AccessTokenIntrospectResponse, AccessTokenRequest,
|
||||||
AccessTokenResponse, AuthorisationResponse, GrantTypeReq, OidcDiscoveryResponse,
|
AccessTokenResponse, AuthorisationResponse, GrantTypeReq, OidcDiscoveryResponse,
|
||||||
};
|
};
|
||||||
use oauth2_ext::PkceCodeChallenge;
|
use oauth2_ext::PkceCodeChallenge;
|
||||||
|
use reqwest::header::{HeaderValue, CONTENT_TYPE};
|
||||||
use reqwest::StatusCode;
|
use reqwest::StatusCode;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -318,6 +320,9 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
.expect("Failed to send code exchange request.");
|
.expect("Failed to send code exchange request.");
|
||||||
|
|
||||||
assert!(response.status() == reqwest::StatusCode::OK);
|
assert!(response.status() == reqwest::StatusCode::OK);
|
||||||
|
assert!(
|
||||||
|
response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON))
|
||||||
|
);
|
||||||
assert_no_cache!(response);
|
assert_no_cache!(response);
|
||||||
|
|
||||||
// The body is a json AccessTokenResponse
|
// The body is a json AccessTokenResponse
|
||||||
|
@ -342,6 +347,10 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
.expect("Failed to send token introspect request.");
|
.expect("Failed to send token introspect request.");
|
||||||
|
|
||||||
assert!(response.status() == reqwest::StatusCode::OK);
|
assert!(response.status() == reqwest::StatusCode::OK);
|
||||||
|
dbg!(response.headers());
|
||||||
|
assert!(
|
||||||
|
response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON))
|
||||||
|
);
|
||||||
assert_no_cache!(response);
|
assert_no_cache!(response);
|
||||||
|
|
||||||
let tir = response
|
let tir = response
|
||||||
|
@ -384,6 +393,10 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
.await
|
.await
|
||||||
.expect("Failed to send userinfo request.");
|
.expect("Failed to send userinfo request.");
|
||||||
|
|
||||||
|
dbg!(response.headers());
|
||||||
|
assert!(
|
||||||
|
response.headers().get(CONTENT_TYPE) == Some(&HeaderValue::from_static(APPLICATION_JSON))
|
||||||
|
);
|
||||||
let userinfo = response
|
let userinfo = response
|
||||||
.json::<OidcToken>()
|
.json::<OidcToken>()
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use kanidm_client::KanidmClient;
|
use kanidm_client::KanidmClient;
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
|
||||||
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
|
@ -14,7 +16,7 @@ async fn test_v1_person_patch(rsclient: KanidmClient) {
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.patch(format!("{}/v1/person/foo", &addr))
|
.patch(format!("{}/v1/person/foo", &addr))
|
||||||
.header("Content-Type", "application/json")
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.body(post_body)
|
.body(post_body)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -635,6 +635,34 @@ async fn test_server_rest_posix_auth_lifecycle(rsclient: KanidmClient) {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// test sending a faulty JSON blob to the person unix update endpoint
|
||||||
|
let bad_json: serde_json::Value = serde_json::json!({
|
||||||
|
"shell" : "test_value",
|
||||||
|
"gidnumber" : "5" // this should be a u32, but it's not!
|
||||||
|
});
|
||||||
|
let res = rsclient
|
||||||
|
.perform_post_request::<serde_json::Value, String>(
|
||||||
|
format!("/v1/person/{}/_unix", "posix_account").as_str(),
|
||||||
|
bad_json,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
dbg!(&res);
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
|
// test sending a faulty JSON blob to the person unix update endpoint
|
||||||
|
let bad_json: serde_json::Value = serde_json::json!({
|
||||||
|
"crab" : "cakes", // this is an invalid field.
|
||||||
|
"gidnumber" : 5
|
||||||
|
});
|
||||||
|
let res = rsclient
|
||||||
|
.perform_post_request::<serde_json::Value, String>(
|
||||||
|
format!("/v1/person/{}/_unix", "posix_account").as_str(),
|
||||||
|
bad_json,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
dbg!(&res);
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
// attempt to verify (good, anon-conn)
|
// attempt to verify (good, anon-conn)
|
||||||
let r1 = anon_rsclient
|
let r1 = anon_rsclient
|
||||||
.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD)
|
.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD)
|
||||||
|
|
|
@ -1,681 +0,0 @@
|
||||||
use kanidm_client::KanidmClient;
|
|
||||||
|
|
||||||
#[kanidmd_testkit::test]
|
|
||||||
async fn test_routes(rsclient: KanidmClient) {
|
|
||||||
let routemap = r#"
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"path": "/",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/robots.txt",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/manifest.webmanifest",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/ui",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/ui/login",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_unix/_token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_radius/_token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_unix/_token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/:rs_name/_icon",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/status",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise/permit",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise/permit",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise/reject",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/authorise/reject",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/token",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/token/introspect",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/token/revoke",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/openid/:client_id/.well-known/openid-configuration",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/openid/:client_id/userinfo",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/oauth2/openid/:client_id/public_key.jwk",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/scim/v1/Sync",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/scim/v1/Sync",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/scim/v1/Sink",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id/_finalise",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id/_terminate",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id/_sync_token",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/sync_account/:id/_sync_token",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/raw/create",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/raw/modify",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/raw/delete",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/raw/search",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/auth",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/auth/valid",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/reauth",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/logout",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/attributetype",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/attributetype",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/attributetype/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/attributetype/:id",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/attributetype/:id",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/classtype",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/classtype",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/classtype/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/classtype/:id",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/schema/classtype/:id",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/_basic",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/:rs_name",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/:rs_name",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/:rs_name",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/:rs_name/_basic_secret",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/_scopemap/:id/:group",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/_scopemap/:id/:group",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/_sup_scopemap/:id/:group",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/oauth2/_sup_scopemap/:id/:group",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_uat",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_credential",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_credential/:cid/_lock",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius/_config",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius/_config/:token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_radius/_config/:token/apple",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/self/_applinks",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_attr/:attr",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_attr/:attr",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_attr/:attr",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_lock",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential/_status",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential/:cid/_lock",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential/_update",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential/_update_intent",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_credential/_update_intent/:ttl",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_ssh_pubkeys",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_ssh_pubkeys",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_ssh_pubkeys/:tag",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_ssh_pubkeys/:tag",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_radius",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_radius",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_radius",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_unix",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_unix/_credential",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/person/:id/_unix/_credential",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id",
|
|
||||||
"method": "PATCH"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_attr/:attr",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_attr/:attr",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_attr/:attr",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_lock",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_into_person",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_api_token",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_api_token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_api_token/:token_id",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_credential",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_credential/_generate",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_credential/_status",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_credential/:cid/_lock",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_ssh_pubkeys",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_ssh_pubkeys",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_ssh_pubkeys/:tag",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_ssh_pubkeys/:tag",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/service_account/:id/_unix",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_unix/_auth",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_ssh_pubkeys",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_ssh_pubkeys/:tag",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_user_auth_token",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/account/:id/_user_auth_token/:token_id",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/credential/_exchange_intent",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/credential/_status",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/credential/_update",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/credential/_commit",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/credential/_cancel",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_attr/:attr",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_attr/:attr",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_attr/:attr",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/group/:id/_unix",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/domain",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/domain/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/domain/_attr/:attr",
|
|
||||||
"method": "PUT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/domain/_attr/:attr",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/system",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/system/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/system/_attr/:attr",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/system/_attr/:attr",
|
|
||||||
"method": "DELETE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/recycle_bin",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/recycle_bin/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/recycle_bin/:id/_revive",
|
|
||||||
"method": "POST"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/access_profile",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/access_profile/:id",
|
|
||||||
"method": "GET"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/v1/access_profile/:id/_attr/:attr",
|
|
||||||
"method": "GET"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"#;
|
|
||||||
// ,{
|
|
||||||
// "path": "/v1/routemap",
|
|
||||||
// "method": "GET"
|
|
||||||
// }
|
|
||||||
let routelist: Vec<serde_json::Value> = serde_json::from_str(routemap).unwrap();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
|
||||||
.danger_accept_invalid_certs(true)
|
|
||||||
.danger_accept_invalid_hostnames(true)
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
for route in routelist {
|
|
||||||
// println!("{:?}", route);
|
|
||||||
let path: String = route.get("path").unwrap().to_string();
|
|
||||||
let method: String = route.get("method").unwrap().to_string();
|
|
||||||
let method = method.replace('"', "");
|
|
||||||
let method = method.as_str();
|
|
||||||
println!("'{method}'");
|
|
||||||
let method = match method {
|
|
||||||
"GET" => reqwest::Method::GET,
|
|
||||||
"POST" => reqwest::Method::POST,
|
|
||||||
"DELETE" => reqwest::Method::DELETE,
|
|
||||||
"PATCH" => reqwest::Method::PATCH,
|
|
||||||
"PUT" => reqwest::Method::PUT,
|
|
||||||
_ => todo!("{}", method),
|
|
||||||
};
|
|
||||||
if path.contains(':') {
|
|
||||||
println!("Can't do this because it has an attribute: {}", path);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let url = format!("{}{}", rsclient.get_url(), path.replace('"', ""));
|
|
||||||
|
|
||||||
println!("#### {:?} {} {}", method, path, url);
|
|
||||||
|
|
||||||
let res = match client
|
|
||||||
.request(method, &url)
|
|
||||||
// .version(http::Version::HTTP_11)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(error) => {
|
|
||||||
panic!("Failed to query {:?} : {:#?}", url, error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if res.status() == 404 {
|
|
||||||
panic!("Failed to query {:?} : {:#?}", url, res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -234,7 +234,7 @@ function addBorrowedObject(obj) {
|
||||||
}
|
}
|
||||||
function __wbg_adapter_48(arg0, arg1, arg2) {
|
function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he237e4e531e49fe1(arg0, arg1, addBorrowedObject(arg2));
|
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hc988533207355089(arg0, arg1, addBorrowedObject(arg2));
|
||||||
} finally {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
heap[stack_pointer++] = undefined;
|
||||||
}
|
}
|
||||||
|
@ -242,14 +242,14 @@ function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||||
|
|
||||||
function __wbg_adapter_51(arg0, arg1, arg2) {
|
function __wbg_adapter_51(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hc1460e7f28360ed3(arg0, arg1, addBorrowedObject(arg2));
|
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha34c6831d0d6d86f(arg0, arg1, addBorrowedObject(arg2));
|
||||||
} finally {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
heap[stack_pointer++] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wbg_adapter_54(arg0, arg1, arg2) {
|
function __wbg_adapter_54(arg0, arg1, arg2) {
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha2ecae7653526986(arg0, arg1, addHeapObject(arg2));
|
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h52363d7e83a077de(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,13 +356,13 @@ function __wbg_get_imports() {
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_modalhidebyid_14daee5d362376c0 = function(arg0, arg1) {
|
|
||||||
modal_hide_by_id(getStringFromWasm0(arg0, arg1));
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||||
const ret = getObject(arg0);
|
const ret = getObject(arg0);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_modalhidebyid_a36f33eb8222a059 = function(arg0, arg1) {
|
||||||
|
modal_hide_by_id(getStringFromWasm0(arg0, arg1));
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
|
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
|
||||||
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -411,11 +411,14 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0) === undefined;
|
const ret = getObject(arg0) === undefined;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
|
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
||||||
const ret = getObject(arg1).__yew_subtree_cache_key;
|
const ret = getObject(arg1).__yew_listener_id;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
||||||
|
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
||||||
|
};
|
||||||
imports.wbg.__wbg_subtreeid_e348577f7ef777e3 = function(arg0, arg1) {
|
imports.wbg.__wbg_subtreeid_e348577f7ef777e3 = function(arg0, arg1) {
|
||||||
const ret = getObject(arg1).__yew_subtree_id;
|
const ret = getObject(arg1).__yew_subtree_id;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||||
|
@ -424,16 +427,13 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_setsubtreeid_d32e6327eef1f7fc = function(arg0, arg1) {
|
imports.wbg.__wbg_setsubtreeid_d32e6327eef1f7fc = function(arg0, arg1) {
|
||||||
getObject(arg0).__yew_subtree_id = arg1 >>> 0;
|
getObject(arg0).__yew_subtree_id = arg1 >>> 0;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_setcachekey_80183b7cfc421143 = function(arg0, arg1) {
|
imports.wbg.__wbg_cachekey_b61393159c57fd7b = function(arg0, arg1) {
|
||||||
getObject(arg0).__yew_subtree_cache_key = arg1 >>> 0;
|
const ret = getObject(arg1).__yew_subtree_cache_key;
|
||||||
};
|
|
||||||
imports.wbg.__wbg_listenerid_12315eee21527820 = function(arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).__yew_listener_id;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
getInt32Memory0()[arg0 / 4 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_setlistenerid_3183aae8fa5840fb = function(arg0, arg1) {
|
imports.wbg.__wbg_setcachekey_80183b7cfc421143 = function(arg0, arg1) {
|
||||||
getObject(arg0).__yew_listener_id = arg1 >>> 0;
|
getObject(arg0).__yew_subtree_cache_key = arg1 >>> 0;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||||
const ret = new Error();
|
const ret = new Error();
|
||||||
|
@ -461,9 +461,6 @@ function __wbg_get_imports() {
|
||||||
const ret = arg0;
|
const ret = arg0;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
|
|
||||||
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
|
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
|
||||||
const ret = getObject(arg0) == getObject(arg1);
|
const ret = getObject(arg0) == getObject(arg1);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -495,6 +492,9 @@ function __wbg_get_imports() {
|
||||||
wasm.__wbindgen_free(arg0, arg1 * 4);
|
wasm.__wbindgen_free(arg0, arg1 * 4);
|
||||||
console.warn(...v0);
|
console.warn(...v0);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
|
||||||
|
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
||||||
|
};
|
||||||
imports.wbg.__wbg_documentURI_4bff51077cdeeac1 = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_documentURI_4bff51077cdeeac1 = function() { return handleError(function (arg0, arg1) {
|
||||||
const ret = getObject(arg1).documentURI;
|
const ret = getObject(arg1).documentURI;
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -564,21 +564,15 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0).fetch(getObject(arg1));
|
const ret = getObject(arg0).fetch(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_addEventListener_a5963e26cd7b176b = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_value_3c5f08ffc2b7d6f9 = function(arg0, arg1) {
|
||||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
const ret = getObject(arg1).value;
|
||||||
}, arguments) };
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
imports.wbg.__wbg_removeEventListener_782040b4432709cb = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
const len1 = WASM_VECTOR_LEN;
|
||||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
}, arguments) };
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
imports.wbg.__wbg_instanceof_HtmlFormElement_b57527983c7c1ada = function(arg0) {
|
};
|
||||||
let result;
|
imports.wbg.__wbg_setvalue_0dc100d4b9908028 = function(arg0, arg1, arg2) {
|
||||||
try {
|
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||||
result = getObject(arg0) instanceof HTMLFormElement;
|
|
||||||
} catch {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
const ret = result;
|
|
||||||
return ret;
|
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_instanceof_ShadowRoot_b64337370f59fe2d = function(arg0) {
|
imports.wbg.__wbg_instanceof_ShadowRoot_b64337370f59fe2d = function(arg0) {
|
||||||
let result;
|
let result;
|
||||||
|
@ -601,6 +595,13 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_pushState_1145414a47c0b629 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
imports.wbg.__wbg_pushState_1145414a47c0b629 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_href_47b90f0ddf3ddcd7 = function(arg0, arg1) {
|
||||||
|
const ret = getObject(arg1).href;
|
||||||
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
const len1 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
|
};
|
||||||
imports.wbg.__wbg_getItem_ed8e218e51f1efeb = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
imports.wbg.__wbg_getItem_ed8e218e51f1efeb = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||||
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
const ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
||||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -614,16 +615,6 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_setItem_d002ee486462bfff = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_setItem_d002ee486462bfff = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_value_3c5f08ffc2b7d6f9 = function(arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).value;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setvalue_0dc100d4b9908028 = function(arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_instanceof_HtmlInputElement_31b50e0cf542c524 = function(arg0) {
|
imports.wbg.__wbg_instanceof_HtmlInputElement_31b50e0cf542c524 = function(arg0) {
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
|
@ -651,6 +642,12 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_setvalue_1f95e61cbc382f7f = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_setvalue_1f95e61cbc382f7f = function(arg0, arg1, arg2) {
|
||||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_add_3eafedc4b2a28db0 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_remove_8ae45e50cb58bb66 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_instanceof_Element_4622f5da1249a3eb = function(arg0) {
|
imports.wbg.__wbg_instanceof_Element_4622f5da1249a3eb = function(arg0) {
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
|
@ -715,20 +712,6 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_set_b34caba58723c454 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_set_b34caba58723c454 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_href_47b90f0ddf3ddcd7 = function(arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).href;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function(arg0) {
|
|
||||||
console.log(getObject(arg0));
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_credentials_66b6baa89eb03c21 = function(arg0) {
|
|
||||||
const ret = getObject(arg0).credentials;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_headers_b439dcff02e808e5 = function(arg0) {
|
imports.wbg.__wbg_headers_b439dcff02e808e5 = function(arg0) {
|
||||||
const ret = getObject(arg0).headers;
|
const ret = getObject(arg0).headers;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -737,12 +720,16 @@ function __wbg_get_imports() {
|
||||||
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_newwithform_368648c82279d486 = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_create_c7e40b6b88186cbf = function() { return handleError(function (arg0, arg1) {
|
||||||
const ret = new FormData(getObject(arg0));
|
const ret = getObject(arg0).create(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_get_4c356dcef81d58a5 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_get_e66794f89dcd7828 = function() { return handleError(function (arg0, arg1) {
|
||||||
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
|
const ret = getObject(arg0).get(getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_credentials_66b6baa89eb03c21 = function(arg0) {
|
||||||
|
const ret = getObject(arg0).credentials;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_instanceof_Response_fc4327dbfcdf5ced = function(arg0) {
|
imports.wbg.__wbg_instanceof_Response_fc4327dbfcdf5ced = function(arg0) {
|
||||||
|
@ -767,14 +754,9 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0).json();
|
const ret = getObject(arg0).json();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_create_c7e40b6b88186cbf = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function(arg0) {
|
||||||
const ret = getObject(arg0).create(getObject(arg1));
|
console.log(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
};
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_get_e66794f89dcd7828 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = getObject(arg0).get(getObject(arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_target_f171e89c61e2bccf = function(arg0) {
|
imports.wbg.__wbg_target_f171e89c61e2bccf = function(arg0) {
|
||||||
const ret = getObject(arg0).target;
|
const ret = getObject(arg0).target;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
@ -794,6 +776,49 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_preventDefault_24104f3f0a54546a = function(arg0) {
|
imports.wbg.__wbg_preventDefault_24104f3f0a54546a = function(arg0) {
|
||||||
getObject(arg0).preventDefault();
|
getObject(arg0).preventDefault();
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_newwithform_368648c82279d486 = function() { return handleError(function (arg0) {
|
||||||
|
const ret = new FormData(getObject(arg0));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_get_4c356dcef81d58a5 = function(arg0, arg1, arg2) {
|
||||||
|
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_href_d62a28e4fc1ab948 = function() { return handleError(function (arg0, arg1) {
|
||||||
|
const ret = getObject(arg1).href;
|
||||||
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
const len1 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_pathname_c8fd5c498079312d = function() { return handleError(function (arg0, arg1) {
|
||||||
|
const ret = getObject(arg1).pathname;
|
||||||
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
const len1 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_search_6c3c472e076ee010 = function() { return handleError(function (arg0, arg1) {
|
||||||
|
const ret = getObject(arg1).search;
|
||||||
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
const len1 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_hash_a1a795b89dda8e3d = function() { return handleError(function (arg0, arg1) {
|
||||||
|
const ret = getObject(arg1).hash;
|
||||||
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
const len1 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_replace_5d1d2b7956cafd7b = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_getClientExtensionResults_b9108fbba9f54b38 = function(arg0) {
|
||||||
|
const ret = getObject(arg0).getClientExtensionResults();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
imports.wbg.__wbg_parentNode_9e53f8b17eb98c9d = function(arg0) {
|
imports.wbg.__wbg_parentNode_9e53f8b17eb98c9d = function(arg0) {
|
||||||
const ret = getObject(arg0).parentNode;
|
const ret = getObject(arg0).parentNode;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
@ -832,47 +857,6 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0).removeChild(getObject(arg1));
|
const ret = getObject(arg0).removeChild(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_getClientExtensionResults_b9108fbba9f54b38 = function(arg0) {
|
|
||||||
const ret = getObject(arg0).getClientExtensionResults();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_add_3eafedc4b2a28db0 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_remove_8ae45e50cb58bb66 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_href_d62a28e4fc1ab948 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).href;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_pathname_c8fd5c498079312d = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).pathname;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_search_6c3c472e076ee010 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).search;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_hash_a1a795b89dda8e3d = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = getObject(arg1).hash;
|
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
const len1 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_replace_5d1d2b7956cafd7b = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_href_17ed54b321396524 = function(arg0, arg1) {
|
imports.wbg.__wbg_href_17ed54b321396524 = function(arg0, arg1) {
|
||||||
const ret = getObject(arg1).href;
|
const ret = getObject(arg1).href;
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -915,6 +899,22 @@ function __wbg_get_imports() {
|
||||||
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
|
const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_addEventListener_a5963e26cd7b176b = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
|
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_removeEventListener_782040b4432709cb = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
|
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_instanceof_HtmlFormElement_b57527983c7c1ada = function(arg0) {
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = getObject(arg0) instanceof HTMLFormElement;
|
||||||
|
} catch {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
const ret = result;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbg_get_44be0491f933a435 = function(arg0, arg1) {
|
imports.wbg.__wbg_get_44be0491f933a435 = function(arg0, arg1) {
|
||||||
const ret = getObject(arg0)[arg1 >>> 0];
|
const ret = getObject(arg0)[arg1 >>> 0];
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -1123,16 +1123,16 @@ function __wbg_get_imports() {
|
||||||
const ret = wasm.memory;
|
const ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2610 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2586 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1223, __wbg_adapter_48);
|
const ret = makeMutClosure(arg0, arg1, 1198, __wbg_adapter_48);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper3431 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2813 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1533, __wbg_adapter_51);
|
const ret = makeMutClosure(arg0, arg1, 1257, __wbg_adapter_51);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper4517 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2986 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1592, __wbg_adapter_54);
|
const ret = makeMutClosure(arg0, arg1, 1319, __wbg_adapter_54);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
//! Constants
|
//! Constants
|
||||||
|
|
||||||
|
pub const CONTENT_TYPE: &str = "content-type";
|
||||||
|
|
||||||
// CSS classes that get applied to full-page forms
|
// CSS classes that get applied to full-page forms
|
||||||
pub const CSS_CLASSES_BODY_FORM: &[&str] = &["flex-column", "d-flex", "h-100"];
|
pub const CSS_CLASSES_BODY_FORM: &[&str] = &["flex-column", "d-flex", "h-100"];
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#![allow(clippy::disallowed_types)]
|
#![allow(clippy::disallowed_types)]
|
||||||
|
|
||||||
use error::FetchError;
|
use error::FetchError;
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
|
@ -83,7 +84,7 @@ pub async fn do_request(
|
||||||
let request = Request::new_with_str_and_init(uri, &opts)?;
|
let request = Request::new_with_str_and_init(uri, &opts)?;
|
||||||
request
|
request
|
||||||
.headers()
|
.headers()
|
||||||
.set("content-type", "application/json")
|
.set(crate::constants::CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.expect_throw("failed to set content-type header");
|
.expect_throw("failed to set content-type header");
|
||||||
|
|
||||||
if let Some(sessionid) = models::pop_auth_session_id() {
|
if let Some(sessionid) = models::pop_auth_session_id() {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
|
use kanidm_proto::constants::APPLICATION_JSON;
|
||||||
pub use kanidm_proto::oauth2::{
|
pub use kanidm_proto::oauth2::{
|
||||||
AccessTokenRequest, AccessTokenResponse, AuthorisationRequest, AuthorisationResponse,
|
AccessTokenRequest, AccessTokenResponse, AuthorisationRequest, AuthorisationResponse,
|
||||||
CodeChallengeMethod, ErrorResponse,
|
CodeChallengeMethod, ErrorResponse,
|
||||||
|
@ -146,9 +147,10 @@ impl Oauth2App {
|
||||||
opts.body(Some(&consentreq_jsvalue));
|
opts.body(Some(&consentreq_jsvalue));
|
||||||
|
|
||||||
let request = Request::new_with_str_and_init("/oauth2/authorise/permit", &opts)?;
|
let request = Request::new_with_str_and_init("/oauth2/authorise/permit", &opts)?;
|
||||||
|
|
||||||
request
|
request
|
||||||
.headers()
|
.headers()
|
||||||
.set("content-type", "application/json")
|
.set(crate::constants::CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.expect_throw("failed to set header");
|
.expect_throw("failed to set header");
|
||||||
|
|
||||||
if let Some(bearer_token) = models::get_bearer_token() {
|
if let Some(bearer_token) = models::get_bearer_token() {
|
||||||
|
|
|
@ -137,6 +137,7 @@ async fn test_fixture(rsclient: KanidmClient) {
|
||||||
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
||||||
.await;
|
.await;
|
||||||
debug!("auth_simple_password res: {:?}", res);
|
debug!("auth_simple_password res: {:?}", res);
|
||||||
|
dbg!(&res);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
// Not recommended in production!
|
// Not recommended in production!
|
||||||
rsclient
|
rsclient
|
||||||
|
|
Loading…
Reference in a new issue