Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use self::sys::responses::WrappingLookupResponse;
/// are automatically logged accordingly.
#[derive(Deserialize, Debug)]
pub struct EndpointResult<T> {
pub data: Option<T>,
pub data: Option<EitherData<T>>,
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Also worth pointing out explicitly why this was changed:

as it seems that for currently implemented auth methods there is no "data" field returned for login api but for ldap/login it returns "data": {} for some reason and that breaks normal deserialisation. This "either data" structure ensures that if unexpectedly data field was returned it still can parse json object.

pub auth: Option<AuthInfo>,
pub lease_id: String,
pub lease_duration: u32,
Expand All @@ -40,6 +40,14 @@ pub struct EndpointResult<T> {
pub wrap_info: Option<WrapInfo>,
}

/// Fixes deserializing empty "data" if it is returned by API as empty object
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum EitherData<T> {
Real(T),
Empty {},
}

impl<T: DeserializeOwned + Send + Sync> rustify::endpoint::Wrapper for EndpointResult<T> {
type Value = T;
}
Expand Down Expand Up @@ -365,7 +373,11 @@ where
true => {}
}
}
result.data
match result.data {
None => None,
Some(EitherData::Empty {}) => None,
Some(EitherData::Real(data)) => Some(data),
}
}

/// Attempts to parse the enclosed API errors returned from a
Expand Down
1 change: 1 addition & 0 deletions src/api/auth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod approle;
pub mod aws;
pub mod kubernetes;
pub mod ldap;
pub mod oidc;
pub mod userpass;
2 changes: 2 additions & 0 deletions src/api/auth/ldap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod requests;
pub mod responses;
242 changes: 242 additions & 0 deletions src/api/auth/ldap/requests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
use super::responses::{
ListLDAPGroupsResponse, ListLDAPUsersResponse, ReadLDAPGroupResponse, ReadLDAPUserResponse,
};
use rustify_derive::Endpoint;

/// ## Configure Client
/// Configures LDAP endpoint.
///
/// * Path: /auth/{self.mount}/config
/// * Method: POST
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#configure-ldap
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(path = "/auth/{self.mount}/config", method = "POST", builder = "true")]
#[builder(setter(into, strip_option), default)]
pub struct ConfigureClientRequest {
#[endpoint(skip)]
pub mount: String,
pub url: Option<String>,
pub case_sensitive_names: Option<bool>,
pub request_timeout: Option<String>,
pub starttls: Option<bool>,
pub tls_min_version: Option<String>,
pub tls_max_version: Option<String>,
pub insecure_tls: Option<bool>,
pub certificate: Option<String>,
pub client_tls_cert: Option<String>,
pub client_tls_key: Option<String>,
pub binddn: Option<String>,
pub bindpass: Option<String>,
pub userdn: Option<String>,
pub userattr: Option<String>,
pub discoverdn: Option<bool>,
pub deny_null_bind: Option<bool>,
pub upndomain: Option<String>,
pub userfilter: Option<String>,
pub anonymous_group_search: Option<bool>,
pub groupfilter: Option<String>,
pub groupdn: Option<String>,
pub groupattr: Option<String>,
pub username_as_alias: Option<bool>,
pub token_ttl: Option<String>,
Comment on lines +41 to +42
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

According to the documentation Vault add some parameters to the auth method.

Suggested change
pub username_as_alias: Option<bool>,
pub token_ttl: Option<String>,
pub username_as_alias: Option<bool>,
pub dereference_aliases: Option<String>,
pub max_page_size: Option<u32>,
pub use_token_groups: Option<bool>,
pub token_ttl: Option<String>,

pub token_max_ttl: Option<String>,
pub token_policies: Option<String>,
pub token_bound_cidrs: Option<String>,
pub token_explicit_max_ttl: Option<String>,
pub token_no_default_policy: Option<bool>,
pub token_num_uses: Option<i64>,
pub token_period: Option<String>,
pub token_type: Option<String>,
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we can add the Read LDAP configuration Endpoint as well.

/// ## List LDAP groups
/// Returns a list of existing groups.
///
/// * Path: /auth/{self.mount}/groups
/// * Method: LIST
/// * Response: [ListLDAPGroupsResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#list-ldap-groups
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups",
method = "LIST",
response = "ListLDAPGroupsResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ListLDAPGroupsRequest {
#[endpoint(skip)]
pub mount: String,
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should also add the List LDAP groups Endpoint.

/// ## Read LDAP Group
/// Reads the policies associated with a LDAP group.
///
/// * Path: /auth/{self.mount}/groups/{self.groupname}
/// * Method: GET
/// * Response: [ReadLDAPGroupResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#read-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.groupname}",
response = "ReadLDAPGroupResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ReadLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub groupname: String,
}
Comment on lines +73 to +92
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

According to the official documentation we should change it from groupname to name.

Suggested change
/// ## Read LDAP Group
/// Reads the policies associated with a LDAP group.
///
/// * Path: /auth/{self.mount}/groups/{self.groupname}
/// * Method: GET
/// * Response: [ReadLDAPGroupResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#read-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.groupname}",
response = "ReadLDAPGroupResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ReadLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub groupname: String,
}
/// ## Read LDAP Group
/// Reads the policies associated with a LDAP group.
///
/// * Path: /auth/{self.mount}/groups/{self.name}
/// * Method: GET
/// * Response: [ReadLDAPGroupResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#read-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.name}",
response = "ReadLDAPGroupResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ReadLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub name: String,
}


/// ## Create/Update LDAP Group
/// Creates or updates LDAP group policies.
///
/// * Path: /auth/{self.mount}/users/{self.groupname}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// * Path: /auth/{self.mount}/users/{self.groupname}
/// * Path: /auth/{self.mount}/users/{self.name}

/// * Method: POST
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#create-update-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.groupname}",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
path = "/auth/{self.mount}/groups/{self.groupname}",
path = "/auth/{self.mount}/groups/{self.name}",

method = "POST",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct CreateLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub groupname: String,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pub groupname: String,
pub name: String,

pub policies: String,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The policies parameter isn't required.

Suggested change
pub policies: String,
pub policies: Option<String>,

}

/// ## Delete LDAP Group
/// Deletes the LDAP group and policy association.
///
/// * Path: /auth/{self.mount}/groups/{self.groupname}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#delete-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.groupname}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub groupname: String,
}
Comment on lines +116 to +135
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// ## Delete LDAP Group
/// Deletes the LDAP group and policy association.
///
/// * Path: /auth/{self.mount}/groups/{self.groupname}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#delete-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.groupname}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub groupname: String,
}
/// ## Delete LDAP Group
/// Deletes the LDAP group and policy association.
///
/// * Path: /auth/{self.mount}/groups/{self.name}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#delete-ldap-group
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/groups/{self.name}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteLDAPGroupRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub name: String,
}


/// ## Create/Update LDAP User
/// This endpoint creates or updates LDAP users policies and group associations.
///
/// * Path: /auth/{self.mount}/users/{self.username}
/// * Method: POST
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#create-update-ldap-user
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/users/{self.username}",
method = "POST",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct CreateLDAPUserRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub username: String,
pub policies: String,
pub groups: String,
Comment on lines +156 to +157
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These parameters are also Optional.

Suggested change
pub policies: String,
pub groups: String,
pub policies: Option<String>,
pub groups: Option<String>,

}

/// ## Read LDAP User
/// Reads the properties of an existing username.
///
/// * Path: /auth/{self.mount}/users/{self.username}
/// * Method: GET
/// * Response: [ReadUserResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#read-ldap-user
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/users/{self.username}",
response = "ReadLDAPUserResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ReadLDAPUserRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub username: String,
}

/// ## List Users
/// List available LDAP users.
///
/// * Path: /auth/{self.mount}/users
/// * Method: LIST
/// * Response: [ListLDAPUsersResponse]
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#list-ldap-users
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/users",
method = "LIST",
response = "ListLDAPUsersResponse",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct ListLDAPUsersRequest {
#[endpoint(skip)]
pub mount: String,
}

/// ## Delete User
/// This endpoint deletes the LDAP user and policy association.
///
/// * Path: /auth/{self.mount}/users/{self.username}
/// * Method: DELETE
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#delete-ldap-user
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/users/{self.username}",
method = "DELETE",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct DeleteLDAPUserRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub username: String,
}

/// ## Login
/// Login with the username and password.
///
/// * Path: /auth/{self.mount}/login/{self.username}
/// * Method: POST
/// * Response: N/A
/// * Reference: https://www.vaultproject.io/api-docs/auth/ldap#login-with-ldap-user
#[derive(Builder, Debug, Default, Endpoint)]
#[endpoint(
path = "/auth/{self.mount}/login/{self.username}",
method = "POST",
builder = "true"
)]
#[builder(setter(into, strip_option), default)]
pub struct LoginRequest {
#[endpoint(skip)]
pub mount: String,
#[endpoint(skip)]
pub username: String,
pub password: String,
}
30 changes: 30 additions & 0 deletions src/api/auth/ldap/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use serde::{Deserialize, Serialize};

/// Response from executing
/// [ListLDAPGroupsRequest][crate::api::auth::ldap::requests::ListLDAPGroupsRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ListLDAPGroupsResponse {
pub keys: Vec<String>,
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would be nice if we can add the Response for the Configure LDAP and Read LDAP configuration the as well.

/// Response from executing
/// [ReadLDAPGroupRequest][crate::api::auth::ldap::requests::ReadLDAPGroupRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ReadLDAPGroupResponse {
pub policies: Vec<String>,
}

/// Response from executing
/// [ListLDAPUsersRequest][crate::api::auth::ldap::requests::ListLDAPUsersRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ListLDAPUsersResponse {
pub keys: Vec<String>,
}

/// Response from executing
/// [ReadLDAPUserRequest][crate::api::auth::ldap::requests::ReadLDAPUserRequest]
#[derive(Deserialize, Debug, Serialize)]
pub struct ReadLDAPUserResponse {
pub policies: Vec<String>,
pub groups: String,
}
1 change: 1 addition & 0 deletions src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod approle;
pub mod aws;
pub mod kubernetes;
pub mod ldap;
pub mod oidc;
pub mod userpass;
Loading