1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*!
# Keycloak Admin REST API
## Legal
Dual-licensed under `MIT` or the [UNLICENSE](http://unlicense.org/).
## Features
Implements [Keycloak Admin REST API version 26.6.0](https://www.keycloak.org/docs-api/26.6.0/rest-api/index.html).
### Feature flags
Default flags: `tags-all`, `resource-builder`, `reqwest`.
- `rc`: use `Arc` for deserialization.
- `schemars`: add [schemars](https://crates.io/crates/schemars) support.
- `multipart`: add multipart support to reqwest, enabling extra methods in API.
- `tags-all`: activate all tags (resource groups) in REST API, it is default behavior. Disable default features and use individual `tag-xxx` features to activate only required resource groups. For a full list reference the [Cargo.toml](Cargo.toml).
- `resource-builder`: add resource builder support.
- `reqwest`: use up to date [reqwest](https://crates.io/crates/reqwest) version (`reqwest 0.13.x`).
- `reqwest12`: use `reqwest 0.12.x`.
- `reqwest13`: use `reqwest 0.13.x`.
## Usage
Requires Rust version >= `1.87.0`.
Add dependency to Cargo.toml:
```toml
[dependencies]
keycloak = "~26.6"
```
```rust, no_run
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
use keycloak::{prelude::reqwest, types::*, KeycloakAdmin, KeycloakAdminToken};
const REALM: &str = "resource";
let url = std::env::var("KEYCLOAK_ADDR").unwrap_or_else(|_| "http://localhost:8080".into());
let user = std::env::var("KEYCLOAK_USER").unwrap_or_else(|_| "admin".into());
let password = std::env::var("KEYCLOAK_PASSWORD").unwrap_or_else(|_| "password".into());
let client = reqwest::Client::new();
let admin_token = KeycloakAdminToken::acquire(&url, &user, &password, &client).await?;
eprintln!("{admin_token:?}");
let admin = KeycloakAdmin::new(&url, admin_token, client);
admin
.post(RealmRepresentation {
realm: Some(REALM.into()),
..Default::default()
})
.await?;
let realm = admin.realm(REALM);
let response = realm
.users_post(UserRepresentation {
username: Some("user".into()),
..Default::default()
})
.await?;
eprintln!("{:?}", response.to_id());
let users = realm.users_get().username("user".to_string()).await?;
eprintln!("{users:?}");
let id = users
.iter()
.find(|u| u.username == Some("user".into()))
.unwrap()
.id
.as_ref()
.unwrap()
.to_string();
realm.users_with_user_id_delete(id.as_str()).await?;
realm.delete().await?;
Ok(())
}
```
## Version agreement
If we have `x.y.z` version of `keycloak`, our package version would be `x.y.(z * 100 + v)` there v is a minor
fix version to official `x.y.z` version.
Example: official version `13.0.1` is `13.0.100` for crate version. `13.0.102` means keycloak version `13.0.1` and minor fix version `2`.
## Update
To update current version use provided [update.ts](./update.ts) `deno` script:
```sh
deno run --allow-env=KEYCLOAK_RUST_VERSION,KEYCLOAK_VERSION,KEYCLOAK_RUST_MAJOR_VERSION --allow-read=Cargo.toml --allow-write=Cargo.toml,api/openapi.json,src/types.rs,src/rest/generated_rest,src/resource --allow-net=keycloak.org,www.keycloak.org --allow-run=cargo,gh,git,handlebars-magic update.ts
```
*/
pub use KeycloakError;
pub use ;