pub struct LdapClient { /* private fields */ }Expand description
High-level LDAP client wrapper on top of ldap3 crate. This wrapper provides a high-level interface to perform LDAP operations including authentication, search, update, delete
Implementations§
Source§impl LdapClient
impl LdapClient
Source§impl LdapClient
impl LdapClient
Sourcepub fn get_inner(&self) -> Ldap
👎Deprecated: This abstraction leakage will be removed in a future release.
Use the provided methods instead. If something’s missing, open an issue in github.
pub fn get_inner(&self) -> Ldap
This abstraction leakage will be removed in a future release. Use the provided methods instead. If something’s missing, open an issue in github.
Returns the ldap3 client
Sourcepub async fn unbind(self) -> Result<(), Error>
pub async fn unbind(self) -> Result<(), Error>
End the LDAP connection.
Caution advised!
This will close the connection for all clones of this client as well, including open streams. So make sure that you’re really good to close.
Closing an LDAP connection with an unbind is a curtesy. It’s fine to skip it, and because of the async hurdles outlined above, I would perhaps even recommend it.
Sourcepub async fn authenticate(
&mut self,
base: &str,
uid: &str,
password: &str,
filter: Box<dyn Filter>,
) -> Result<(), Error>
pub async fn authenticate( &mut self, base: &str, uid: &str, password: &str, filter: Box<dyn Filter>, ) -> Result<(), Error>
The user is authenticated by searching for the user in the LDAP server. The search is performed using the provided filter. The filter should be a filter that matches a single user.
§Arguments
base- The base DN to search for the useruid- The uid of the userpassword- The password of the userfilter- The filter to search for the user
§Returns
Result<(), Error>- Returns an error if the authentication fails
§Example
use simple_ldap::{
LdapClient, LdapConfig,
filter::EqFilter
};
use url::Url;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let name_filter = EqFilter::from("cn".to_string(), "Sam".to_string());
let result = client.authenticate("", "Sam", "password", Box::new(name_filter)).await;
}Sourcepub async fn search<'a, F, A, S, T>(
&mut self,
base: &str,
scope: Scope,
filter: &F,
attributes: A,
) -> Result<T, Error>
pub async fn search<'a, F, A, S, T>( &mut self, base: &str, scope: Scope, filter: &F, attributes: A, ) -> Result<T, Error>
Search a single value from the LDAP server. The search is performed using the provided filter. The filter should be a filter that matches a single record. if the filter matches multiple users, an error is returned. This operation will treat all the attributes as single-valued, silently ignoring the possible extra values.
§Arguments
base- The base DN to search for the userscope- The scope of the searchfilter- The filter to search for the userattributes- The attributes to return from the search
§Returns
Result<T, Error>- The result will be mapped to a struct of type T
§Example
use simple_ldap::{
LdapClient, LdapConfig,
filter::EqFilter,
ldap3::Scope
};
use url::Url;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct User {
uid: String,
cn: String,
sn: String,
}
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let name_filter = EqFilter::from("cn".to_string(), "Sam".to_string());
let user_result: User = client
.search(
"ou=people,dc=example,dc=com",
Scope::OneLevel,
&name_filter,
vec!["cn", "sn", "uid"],
).await
.unwrap();
}Sourcepub async fn search_multi_valued<T: for<'a> Deserialize<'a>>(
&mut self,
base: &str,
scope: Scope,
filter: &impl Filter,
attributes: &Vec<&str>,
) -> Result<T, Error>
pub async fn search_multi_valued<T: for<'a> Deserialize<'a>>( &mut self, base: &str, scope: Scope, filter: &impl Filter, attributes: &Vec<&str>, ) -> Result<T, Error>
Search a single value from the LDAP server. The search is performed using the provided filter. The filter should be a filter that matches a single record. if the filter matches multiple users, an error is returned. This operation is useful when records has multi-valued attributes.
§Arguments
base- The base DN to search for the userscope- The scope of the searchfilter- The filter to search for the userattributes- The attributes to return from the search
§Returns
Result<T, Error>- The result will be mapped to a struct of type T
§Example
use simple_ldap::{
LdapClient, LdapConfig,
filter::EqFilter,
ldap3::Scope
};
use url::Url;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct TestMultiValued {
key1: Vec<String>,
key2: Vec<String>,
}
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let name_filter = EqFilter::from("cn".to_string(), "Sam".to_string());
let user_result = client.search_multi_valued::<TestMultiValued>(
"",
Scope::OneLevel,
&name_filter,
&vec!["cn", "sn", "uid"]
).await;
}Sourcepub async fn streaming_search<'a, F, A, S>(
&'a mut self,
base: &str,
scope: Scope,
filter: &F,
attributes: A,
page_size: Option<NonZeroU16>,
sort_by: Vec<SortBy>,
) -> Result<impl Stream<Item = Result<Record, Error>> + use<'a, F, A, S>, Error>
pub async fn streaming_search<'a, F, A, S>( &'a mut self, base: &str, scope: Scope, filter: &F, attributes: A, page_size: Option<NonZeroU16>, sort_by: Vec<SortBy>, ) -> Result<impl Stream<Item = Result<Record, Error>> + use<'a, F, A, S>, Error>
This method is used to search multiple records from the LDAP server. The search is performed using the provided filter. Method will return a Stream. The stream will lazily fetch the results, resulting in a smaller memory footprint.
This is the recommended search method, especially if you don’t know that the result set is going to be small.
§Arguments
base- The base DN to search for the userscope- The scope of the searchfilter- The filter to search for the userattributes- The attributes to return from the searchpage_size- Fetch the results in pages. Recommended for large result sets. Uses the Simple Paged Results LDAP extension.sort_by- Sort the results using Server Side Sort LDAP extension.
§Returns
A stream that can be used to iterate through the search results.
§Blocking drop caveat
Dropping this stream may issue blocking network requests to cancel the search. Running the stream to it’s end will minimize the chances of this happening. You should take this into account if latency is critical to your application.
We’re waiting for AsyncDrop for implementing this properly.
§Example
use simple_ldap::{
LdapClient, LdapConfig, SortBy,
filter::EqFilter,
ldap3::Scope,
};
use url::Url;
use serde::Deserialize;
use futures::{StreamExt, TryStreamExt};
use std::num::NonZero;
#[derive(Deserialize, Debug)]
struct User {
uid: String,
cn: String,
sn: String,
}
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let name_filter = EqFilter::from(String::from("cn"), String::from("Sam"));
let attributes = vec!["cn", "sn", "uid"];
let sort = vec![
SortBy {
attribute: String::from("sn"),
reverse: true
}
];
let stream = client.streaming_search(
"ou=people,dc=example,dc=com",
Scope::OneLevel,
&name_filter,
attributes,
Some(NonZero::new(200).unwrap()), // The pagesize
sort
).await.unwrap();
// Map the search results to User type.
stream.and_then(async |record| record.to_record())
// Do something with the Users concurrently.
.try_for_each(async |user: User| {
println!("User: {:?}", user);
Ok(())
})
.await
.unwrap();
}Sourcepub async fn create(
&mut self,
uid: &str,
base: &str,
data: Vec<(&str, HashSet<&str>)>,
) -> Result<(), Error>
pub async fn create( &mut self, uid: &str, base: &str, data: Vec<(&str, HashSet<&str>)>, ) -> Result<(), Error>
Create a new record in the LDAP server. The record will be created in the provided base DN.
§Arguments
uid- The uid of the recordbase- The base DN to create the recorddata- The attributes of the record
§Returns
Result<(), Error>- Returns an error if the record creation fails
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
use std::collections::HashSet;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let data = vec![
( "objectClass",HashSet::from(["organizationalPerson", "inetorgperson", "top", "person"]),),
("uid",HashSet::from(["bd9b91ec-7a69-4166-bf67-cc7e553b2fd9"]),),
("cn", HashSet::from(["Kasun"])),
("sn", HashSet::from(["Ranasingh"])),
];
let result = client.create("bd9b91ec-7a69-4166-bf67-cc7e553b2fd9", "ou=people,dc=example,dc=com", data).await;
}Sourcepub async fn update(
&mut self,
uid: &str,
base: &str,
data: Vec<Mod<&str>>,
new_uid: Option<&str>,
) -> Result<(), Error>
pub async fn update( &mut self, uid: &str, base: &str, data: Vec<Mod<&str>>, new_uid: Option<&str>, ) -> Result<(), Error>
Update a record in the LDAP server. The record will be updated in the provided base DN.
§Arguments
uid- The uid of the recordbase- The base DN to update the recorddata- The attributes of the recordnew_uid- The new uid of the record. If the new uid is provided, the uid of the record will be updated.
§Returns
Result<(), Error>- Returns an error if the record update fails
§Example
use simple_ldap::{
LdapClient, LdapConfig,
ldap3::Mod
};
use url::Url;
use std::collections::HashSet;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let data = vec![
Mod::Replace("cn", HashSet::from(["Jhon_Update"])),
Mod::Replace("sn", HashSet::from(["Eliet_Update"])),
];
let result = client.update(
"e219fbc0-6df5-4bc3-a6ee-986843bb157e",
"ou=people,dc=example,dc=com",
data,
None
).await;
}Sourcepub async fn delete(&mut self, uid: &str, base: &str) -> Result<(), Error>
pub async fn delete(&mut self, uid: &str, base: &str) -> Result<(), Error>
Delete a record in the LDAP server. The record will be deleted in the provided base DN.
§Arguments
uid- The uid of the recordbase- The base DN to delete the record
§Returns
Result<(), Error>- Returns an error if the record delete fails
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let result = client.delete("e219fbc0-6df5-4bc3-a6ee-986843bb157e", "ou=people,dc=example,dc=com").await;
}Sourcepub async fn create_group(
&mut self,
group_name: &str,
group_ou: &str,
description: &str,
) -> Result<(), Error>
pub async fn create_group( &mut self, group_name: &str, group_ou: &str, description: &str, ) -> Result<(), Error>
Create a new group in the LDAP server. The group will be created in the provided base DN.
§Arguments
group_name- The name of the groupgroup_ou- The ou of the groupdescription- The description of the group
§Returns
Result<(), Error>- Returns an error if the group creation fails
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let result = client.create_group("test_group", "ou=groups,dc=example,dc=com", "test group").await;
}Sourcepub async fn add_users_to_group(
&mut self,
users: Vec<&str>,
group_dn: &str,
) -> Result<(), Error>
pub async fn add_users_to_group( &mut self, users: Vec<&str>, group_dn: &str, ) -> Result<(), Error>
Add users to a group in the LDAP server. The group will be updated in the provided base DN.
§Arguments
users- The list of users to add to the groupgroup_dn- The dn of the group
§Returns
Result<(), Error>- Returns an error if failed to add users to the group
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let result = client.add_users_to_group(
vec!["uid=bd9b91ec-7a69-4166-bf67-cc7e553b2fd9,ou=people,dc=example,dc=com"],
"cn=test_group,ou=groups,dc=example,dc=com").await;
}Sourcepub async fn get_members<'a, A, S, T>(
&mut self,
group_dn: &str,
base_dn: &str,
scope: Scope,
attributes: A,
) -> Result<Vec<T>, Error>
pub async fn get_members<'a, A, S, T>( &mut self, group_dn: &str, base_dn: &str, scope: Scope, attributes: A, ) -> Result<Vec<T>, Error>
Get users of a group in the LDAP server. The group will be searched in the provided base DN.
§Arguments
group_dn- The dn of the groupbase_dn- The base dn to search for the usersscope- The scope of the searchattributes- The attributes to return from the search
§Returns
Result<Vec<T>, Error>- Returns a vector of structs of type T
§Example
use simple_ldap::{
LdapClient, LdapConfig,
ldap3::Scope
};
use url::Url;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct User {
uid: String,
cn: String,
sn: String,
}
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let members: Vec<User> = client.get_members(
"cn=test_group,ou=groups,dc=example,dc=com",
"ou=people,dc=example,dc=com",
Scope::OneLevel,
vec!["cn", "sn", "uid"]
).await
.unwrap();
}Sourcepub async fn remove_users_from_group(
&mut self,
group_dn: &str,
users: Vec<&str>,
) -> Result<(), Error>
pub async fn remove_users_from_group( &mut self, group_dn: &str, users: Vec<&str>, ) -> Result<(), Error>
Remove users from a group in the LDAP server. The group will be updated in the provided base DN. This method will remove all the users provided from the group.
§Arguments
group_dn- The dn of the groupusers- The list of users to remove from the group
§Returns
Result<(), Error>- Returns an error if failed to remove users from the group
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
use std::collections::HashSet;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let result = client.remove_users_from_group("cn=test_group,ou=groups,dc=example,dc=com",
vec!["uid=bd9b91ec-7a69-4166-bf67-cc7e553b2fd9,ou=people,dc=example,dc=com"]).await;
}Sourcepub async fn get_associtated_groups(
&mut self,
group_ou: &str,
user_dn: &str,
) -> Result<Vec<String>, Error>
pub async fn get_associtated_groups( &mut self, group_ou: &str, user_dn: &str, ) -> Result<Vec<String>, Error>
Get the groups associated with a user in the LDAP server. The user will be searched in the provided base DN.
§Arguments
group_ou- The ou to search for the groupsuser_dn- The dn of the user
§Returns
Result<Vec<String>, Error>- Returns a vector of group names
§Example
use simple_ldap::{LdapClient, LdapConfig};
use url::Url;
#[tokio::main]
async fn main(){
let ldap_config = LdapConfig {
bind_dn: String::from("cn=manager"),
bind_password: String::from("password"),
ldap_url: Url::parse("ldaps://localhost:1389/dc=example,dc=com").unwrap(),
dn_attribute: None,
connection_settings: None
};
let mut client = LdapClient::new(ldap_config).await.unwrap();
let result = client.get_associtated_groups("ou=groups,dc=example,dc=com",
"uid=bd9b91ec-7a69-4166-bf67-cc7e553b2fd9,ou=people,dc=example,dc=com").await;
}Trait Implementations§
Source§impl Clone for LdapClient
impl Clone for LdapClient
Source§fn clone(&self) -> LdapClient
fn clone(&self) -> LdapClient
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for LdapClient
impl RefUnwindSafe for LdapClient
impl Send for LdapClient
impl Sync for LdapClient
impl Unpin for LdapClient
impl UnsafeUnpin for LdapClient
impl UnwindSafe for LdapClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
Source§impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
Source§fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
WrappingSpan::make_wrapped to wrap an AST node in a span.