etcd_client/rpc/
auth.rs

1//! Etcd Auth RPC.
2
3pub use crate::rpc::pb::authpb::permission::Type as PermissionType;
4
5use crate::error::Result;
6use crate::intercept::InterceptedChannel;
7use crate::rpc::pb::authpb::{Permission as PbPermission, UserAddOptions as PbUserAddOptions};
8use crate::rpc::pb::etcdserverpb::auth_client::AuthClient as PbAuthClient;
9use crate::rpc::pb::etcdserverpb::{
10    AuthDisableRequest as PbAuthDisableRequest, AuthDisableResponse as PbAuthDisableResponse,
11    AuthEnableRequest as PbAuthEnableRequest, AuthEnableResponse as PbAuthEnableResponse,
12    AuthRoleAddRequest as PbAuthRoleAddRequest, AuthRoleAddResponse as PbAuthRoleAddResponse,
13    AuthRoleDeleteRequest as PbAuthRoleDeleteRequest,
14    AuthRoleDeleteResponse as PbAuthRoleDeleteResponse, AuthRoleGetRequest as PbAuthRoleGetRequest,
15    AuthRoleGetResponse as PbAuthRoleGetResponse,
16    AuthRoleGrantPermissionRequest as PbAuthRoleGrantPermissionRequest,
17    AuthRoleGrantPermissionResponse as PbAuthRoleGrantPermissionResponse,
18    AuthRoleListRequest as PbAuthRoleListRequest, AuthRoleListResponse as PbAuthRoleListResponse,
19    AuthRoleRevokePermissionRequest as PbAuthRoleRevokePermissionRequest,
20    AuthRoleRevokePermissionResponse as PbAuthRoleRevokePermissionResponse,
21    AuthUserAddRequest as PbAuthUserAddRequest, AuthUserAddResponse as PbAuthUserAddResponse,
22    AuthUserChangePasswordRequest as PbAuthUserChangePasswordRequest,
23    AuthUserChangePasswordResponse as PbAuthUserChangePasswordResponse,
24    AuthUserDeleteRequest as PbAuthUserDeleteRequest,
25    AuthUserDeleteResponse as PbAuthUserDeleteResponse, AuthUserGetRequest as PbAuthUserGetRequest,
26    AuthUserGetResponse as PbAuthUserGetResponse,
27    AuthUserGrantRoleRequest as PbAuthUserGrantRoleRequest,
28    AuthUserGrantRoleResponse as PbAuthUserGrantRoleResponse,
29    AuthUserListRequest as PbAuthUserListRequest, AuthUserListResponse as PbAuthUserListResponse,
30    AuthUserRevokeRoleRequest as PbAuthUserRevokeRoleRequest,
31    AuthUserRevokeRoleResponse as PbAuthUserRevokeRoleResponse,
32    AuthenticateRequest as PbAuthenticateRequest, AuthenticateResponse as PbAuthenticateResponse,
33};
34use crate::rpc::ResponseHeader;
35use crate::rpc::{get_prefix, KeyRange};
36use tonic::{IntoRequest, Request};
37
38/// Client for Auth operations.
39#[derive(Clone)]
40pub struct AuthClient {
41    inner: PbAuthClient<InterceptedChannel>,
42}
43
44impl AuthClient {
45    /// Creates an auth client.
46    #[inline]
47    pub(crate) fn new(channel: InterceptedChannel) -> Self {
48        let inner = PbAuthClient::new(channel);
49        Self { inner }
50    }
51
52    /// Enables authentication for the etcd cluster.
53    #[inline]
54    pub async fn auth_enable(&mut self) -> Result<AuthEnableResponse> {
55        let resp = self
56            .inner
57            .auth_enable(AuthEnableOptions::new())
58            .await?
59            .into_inner();
60        Ok(AuthEnableResponse::new(resp))
61    }
62
63    /// Disables authentication for the etcd cluster.
64    #[inline]
65    pub async fn auth_disable(&mut self) -> Result<AuthDisableResponse> {
66        let resp = self
67            .inner
68            .auth_disable(AuthDisableOptions::new())
69            .await?
70            .into_inner();
71        Ok(AuthDisableResponse::new(resp))
72    }
73
74    /// Sends an authenticate request.
75    ///
76    /// Note that this does not set or update client-side authentication settings.
77    /// Call [`crate::Client::refresh_token`] instead.
78    #[inline]
79    pub async fn authenticate(
80        &mut self,
81        name: String,
82        password: String,
83    ) -> Result<AuthenticateResponse> {
84        let resp = self
85            .inner
86            .authenticate(AuthenticateOptions::new().with_user(name, password))
87            .await?
88            .into_inner();
89        Ok(AuthenticateResponse::new(resp))
90    }
91
92    /// Adds role
93    #[inline]
94    pub async fn role_add(&mut self, name: impl Into<String>) -> Result<RoleAddResponse> {
95        let resp = self
96            .inner
97            .role_add(RoleAddOptions::new(name.into()))
98            .await?
99            .into_inner();
100        Ok(RoleAddResponse::new(resp))
101    }
102
103    /// Deletes role
104    #[inline]
105    pub async fn role_delete(&mut self, name: impl Into<String>) -> Result<RoleDeleteResponse> {
106        let resp = self
107            .inner
108            .role_delete(RoleDeleteOptions::new(name.into()))
109            .await?
110            .into_inner();
111        Ok(RoleDeleteResponse::new(resp))
112    }
113
114    /// Gets role
115    #[inline]
116    pub async fn role_get(&mut self, name: impl Into<String>) -> Result<RoleGetResponse> {
117        let resp = self
118            .inner
119            .role_get(RoleGetOptions::new(name.into()))
120            .await?
121            .into_inner();
122        Ok(RoleGetResponse::new(resp))
123    }
124
125    /// Lists role
126    #[inline]
127    pub async fn role_list(&mut self) -> Result<RoleListResponse> {
128        let resp = self
129            .inner
130            .role_list(AuthRoleListOptions {})
131            .await?
132            .into_inner();
133        Ok(RoleListResponse::new(resp))
134    }
135
136    /// Grants role permission
137    #[inline]
138    pub async fn role_grant_permission(
139        &mut self,
140        name: impl Into<String>,
141        perm: Permission,
142    ) -> Result<RoleGrantPermissionResponse> {
143        let resp = self
144            .inner
145            .role_grant_permission(RoleGrantPermissionOptions::new(name.into(), perm))
146            .await?
147            .into_inner();
148        Ok(RoleGrantPermissionResponse::new(resp))
149    }
150
151    /// Revokes role permission
152    #[inline]
153    pub async fn role_revoke_permission(
154        &mut self,
155        name: impl Into<String>,
156        key: impl Into<Vec<u8>>,
157        options: Option<RoleRevokePermissionOptions>,
158    ) -> Result<RoleRevokePermissionResponse> {
159        let resp = self
160            .inner
161            .role_revoke_permission(
162                options
163                    .unwrap_or_default()
164                    .with_name(name.into())
165                    .with_key(key.into()),
166            )
167            .await?
168            .into_inner();
169        Ok(RoleRevokePermissionResponse::new(resp))
170    }
171
172    /// Adds user
173    #[inline]
174    pub async fn user_add(
175        &mut self,
176        name: impl Into<String>,
177        password: impl Into<String>,
178        options: Option<UserAddOptions>,
179    ) -> Result<UserAddResponse> {
180        let resp = self
181            .inner
182            .user_add(
183                options
184                    .unwrap_or_default()
185                    .with_name(name.into())
186                    .with_pwd(password.into()),
187            )
188            .await?
189            .into_inner();
190        Ok(UserAddResponse::new(resp))
191    }
192
193    /// Gets user
194    #[inline]
195    pub async fn user_get(&mut self, name: impl Into<String>) -> Result<UserGetResponse> {
196        let resp = self
197            .inner
198            .user_get(UserGetOptions::new(name.into()))
199            .await?
200            .into_inner();
201        Ok(UserGetResponse::new(resp))
202    }
203
204    /// Lists user
205    #[inline]
206    pub async fn user_list(&mut self) -> Result<UserListResponse> {
207        let resp = self
208            .inner
209            .user_list(AuthUserListOptions {})
210            .await?
211            .into_inner();
212        Ok(UserListResponse::new(resp))
213    }
214
215    /// Deletes user
216    #[inline]
217    pub async fn user_delete(&mut self, name: impl Into<String>) -> Result<UserDeleteResponse> {
218        let resp = self
219            .inner
220            .user_delete(UserDeleteOptions::new(name.into()))
221            .await?
222            .into_inner();
223        Ok(UserDeleteResponse::new(resp))
224    }
225
226    /// Change user's password
227    #[inline]
228    pub async fn user_change_password(
229        &mut self,
230        name: impl Into<String>,
231        password: impl Into<String>,
232    ) -> Result<UserChangePasswordResponse> {
233        let resp = self
234            .inner
235            .user_change_password(UserChangePasswordOptions::new(name.into(), password.into()))
236            .await?
237            .into_inner();
238        Ok(UserChangePasswordResponse::new(resp))
239    }
240
241    /// Grant role for an user
242    #[inline]
243    pub async fn user_grant_role(
244        &mut self,
245        name: impl Into<String>,
246        role: impl Into<String>,
247    ) -> Result<UserGrantRoleResponse> {
248        let resp = self
249            .inner
250            .user_grant_role(UserGrantRoleOptions::new(name.into(), role.into()))
251            .await?
252            .into_inner();
253        Ok(UserGrantRoleResponse::new(resp))
254    }
255
256    /// Revoke role for an user
257    #[inline]
258    pub async fn user_revoke_role(
259        &mut self,
260        name: impl Into<String>,
261        role: impl Into<String>,
262    ) -> Result<UserRevokeRoleResponse> {
263        let resp = self
264            .inner
265            .user_revoke_role(UserRevokeRoleOptions::new(name.into(), role.into()))
266            .await?
267            .into_inner();
268        Ok(UserRevokeRoleResponse::new(resp))
269    }
270}
271
272/// Options for `AuthEnable` operation.
273#[derive(Debug, Default, Clone)]
274pub struct AuthEnableOptions(PbAuthEnableRequest);
275
276impl AuthEnableOptions {
277    /// Creates a `AuthEnableOptions`.
278    #[inline]
279    pub const fn new() -> Self {
280        Self(PbAuthEnableRequest {})
281    }
282}
283
284impl From<AuthEnableOptions> for PbAuthEnableRequest {
285    #[inline]
286    fn from(options: AuthEnableOptions) -> Self {
287        options.0
288    }
289}
290
291impl IntoRequest<PbAuthEnableRequest> for AuthEnableOptions {
292    #[inline]
293    fn into_request(self) -> Request<PbAuthEnableRequest> {
294        Request::new(self.into())
295    }
296}
297
298/// Response for `AuthEnable` operation.
299#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
300#[derive(Debug, Default, Clone)]
301#[repr(transparent)]
302pub struct AuthEnableResponse(PbAuthEnableResponse);
303
304impl AuthEnableResponse {
305    /// Creates a new `AuthEnableResponse` from pb auth response.
306    #[inline]
307    const fn new(resp: PbAuthEnableResponse) -> Self {
308        Self(resp)
309    }
310
311    /// Gets response header.
312    #[inline]
313    pub fn header(&self) -> Option<&ResponseHeader> {
314        self.0.header.as_ref().map(From::from)
315    }
316
317    /// Takes the header out of the response, leaving a [`None`] in its place.
318    #[inline]
319    pub fn take_header(&mut self) -> Option<ResponseHeader> {
320        self.0.header.take().map(ResponseHeader::new)
321    }
322}
323
324/// Options for `AuthDisable` operation.
325#[derive(Debug, Default, Clone)]
326pub struct AuthDisableOptions(PbAuthDisableRequest);
327
328impl AuthDisableOptions {
329    /// Creates a `AuthDisableOptions`.
330    #[inline]
331    pub const fn new() -> Self {
332        Self(PbAuthDisableRequest {})
333    }
334}
335
336impl From<AuthDisableOptions> for PbAuthDisableRequest {
337    #[inline]
338    fn from(options: AuthDisableOptions) -> Self {
339        options.0
340    }
341}
342
343impl IntoRequest<PbAuthDisableRequest> for AuthDisableOptions {
344    #[inline]
345    fn into_request(self) -> Request<PbAuthDisableRequest> {
346        Request::new(self.into())
347    }
348}
349
350/// Response for `AuthDisable` operation.
351#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
352#[derive(Debug, Default, Clone)]
353#[repr(transparent)]
354pub struct AuthDisableResponse(PbAuthDisableResponse);
355
356impl AuthDisableResponse {
357    /// Creates a new `AuthDisableResponse` from pb auth response.
358    #[inline]
359    const fn new(resp: PbAuthDisableResponse) -> Self {
360        Self(resp)
361    }
362
363    /// Gets response header.
364    #[inline]
365    pub fn header(&self) -> Option<&ResponseHeader> {
366        self.0.header.as_ref().map(From::from)
367    }
368
369    /// Takes the header out of the response, leaving a [`None`] in its place.
370    #[inline]
371    pub fn take_header(&mut self) -> Option<ResponseHeader> {
372        self.0.header.take().map(ResponseHeader::new)
373    }
374}
375
376/// Options for `Authenticate` operation.
377#[derive(Debug, Default, Clone)]
378#[repr(transparent)]
379pub struct AuthenticateOptions(PbAuthenticateRequest);
380
381impl AuthenticateOptions {
382    /// Sets user's name and password.
383    #[inline]
384    fn with_user(mut self, name: String, password: String) -> Self {
385        self.0.name = name;
386        self.0.password = password;
387        self
388    }
389
390    /// Creates a `AuthenticateOptions`.
391    #[inline]
392    pub const fn new() -> Self {
393        Self(PbAuthenticateRequest {
394            name: String::new(),
395            password: String::new(),
396        })
397    }
398}
399
400impl From<AuthenticateOptions> for PbAuthenticateRequest {
401    #[inline]
402    fn from(options: AuthenticateOptions) -> Self {
403        options.0
404    }
405}
406
407impl IntoRequest<PbAuthenticateRequest> for AuthenticateOptions {
408    #[inline]
409    fn into_request(self) -> Request<PbAuthenticateRequest> {
410        Request::new(self.into())
411    }
412}
413
414/// Response for `Authenticate` operation.
415#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
416#[derive(Debug, Default, Clone)]
417#[repr(transparent)]
418pub struct AuthenticateResponse(PbAuthenticateResponse);
419
420impl AuthenticateResponse {
421    /// Creates a new `AuthenticateResponse` from pb auth response.
422    #[inline]
423    const fn new(resp: PbAuthenticateResponse) -> Self {
424        Self(resp)
425    }
426
427    /// Gets response header.
428    #[allow(dead_code)]
429    #[inline]
430    pub fn header(&self) -> Option<&ResponseHeader> {
431        self.0.header.as_ref().map(From::from)
432    }
433
434    /// Takes the header out of the response, leaving a [`None`] in its place.
435    #[allow(dead_code)]
436    #[inline]
437    pub fn take_header(&mut self) -> Option<ResponseHeader> {
438        self.0.header.take().map(ResponseHeader::new)
439    }
440
441    /// An authorized token that can be used in succeeding RPCs
442    #[inline]
443    pub fn token(&self) -> &str {
444        &self.0.token
445    }
446}
447
448/// Options for `RoleAddOptions` operation.
449#[derive(Debug, Default, Clone)]
450#[repr(transparent)]
451pub struct RoleAddOptions(PbAuthRoleAddRequest);
452
453impl RoleAddOptions {
454    /// Creates a `RoleAddOptions`.
455    #[inline]
456    pub fn new(name: String) -> Self {
457        Self(PbAuthRoleAddRequest { name })
458    }
459}
460
461impl From<RoleAddOptions> for PbAuthRoleAddRequest {
462    #[inline]
463    fn from(options: RoleAddOptions) -> Self {
464        options.0
465    }
466}
467
468impl IntoRequest<PbAuthRoleAddRequest> for RoleAddOptions {
469    #[inline]
470    fn into_request(self) -> Request<PbAuthRoleAddRequest> {
471        Request::new(self.into())
472    }
473}
474
475/// Response for role add operation.
476#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
477#[derive(Debug, Clone)]
478#[repr(transparent)]
479pub struct RoleAddResponse(PbAuthRoleAddResponse);
480
481impl RoleAddResponse {
482    /// Creates a new `RoleAddResponse` from pb role add response.
483    #[inline]
484    const fn new(resp: PbAuthRoleAddResponse) -> Self {
485        Self(resp)
486    }
487
488    /// Gets response header.
489    #[inline]
490    pub fn header(&self) -> Option<&ResponseHeader> {
491        self.0.header.as_ref().map(From::from)
492    }
493
494    /// Takes the header out of the response, leaving a [`None`] in its place.
495    #[inline]
496    pub fn take_header(&mut self) -> Option<ResponseHeader> {
497        self.0.header.take().map(ResponseHeader::new)
498    }
499}
500
501/// Options for delete role operation.
502#[derive(Debug, Default, Clone)]
503#[repr(transparent)]
504pub struct RoleDeleteOptions(PbAuthRoleDeleteRequest);
505
506impl RoleDeleteOptions {
507    /// Creates a `RoleDeleteOptions` to delete role.
508    #[inline]
509    pub fn new(name: String) -> Self {
510        Self(PbAuthRoleDeleteRequest { role: name })
511    }
512}
513
514impl From<RoleDeleteOptions> for PbAuthRoleDeleteRequest {
515    #[inline]
516    fn from(options: RoleDeleteOptions) -> Self {
517        options.0
518    }
519}
520
521impl IntoRequest<PbAuthRoleDeleteRequest> for RoleDeleteOptions {
522    #[inline]
523    fn into_request(self) -> Request<PbAuthRoleDeleteRequest> {
524        Request::new(self.into())
525    }
526}
527
528/// Response for delete role operation.
529#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
530#[derive(Debug, Clone)]
531#[repr(transparent)]
532pub struct RoleDeleteResponse(PbAuthRoleDeleteResponse);
533
534impl RoleDeleteResponse {
535    /// Creates a new `RoleDeleteResponse` from pb role delete response.
536    #[inline]
537    const fn new(resp: PbAuthRoleDeleteResponse) -> Self {
538        Self(resp)
539    }
540
541    /// Gets response header.
542    #[inline]
543    pub fn header(&self) -> Option<&ResponseHeader> {
544        self.0.header.as_ref().map(From::from)
545    }
546
547    /// Takes the header out of the response, leaving a [`None`] in its place.
548    #[inline]
549    pub fn take_header(&mut self) -> Option<ResponseHeader> {
550        self.0.header.take().map(ResponseHeader::new)
551    }
552}
553
554/// Options for get role operation.
555#[derive(Debug, Default, Clone)]
556#[repr(transparent)]
557pub struct RoleGetOptions(PbAuthRoleGetRequest);
558
559impl RoleGetOptions {
560    /// Creates a `RoleGetOptions` to get role.
561    #[inline]
562    pub fn new(name: String) -> Self {
563        Self(PbAuthRoleGetRequest { role: name })
564    }
565}
566
567impl From<RoleGetOptions> for PbAuthRoleGetRequest {
568    #[inline]
569    fn from(options: RoleGetOptions) -> Self {
570        options.0
571    }
572}
573
574impl IntoRequest<PbAuthRoleGetRequest> for RoleGetOptions {
575    #[inline]
576    fn into_request(self) -> Request<PbAuthRoleGetRequest> {
577        Request::new(self.into())
578    }
579}
580
581/// Role access permission.
582#[derive(Debug, Clone)]
583pub struct Permission {
584    inner: PbPermission,
585    with_prefix: bool,
586    with_from_key: bool,
587}
588
589impl Permission {
590    /// Creates a permission with operation type and key
591    #[inline]
592    pub fn new(perm_type: PermissionType, key: impl Into<Vec<u8>>) -> Self {
593        Self {
594            inner: PbPermission {
595                perm_type: perm_type.into(),
596                key: key.into(),
597                range_end: Vec::new(),
598            },
599            with_prefix: false,
600            with_from_key: false,
601        }
602    }
603
604    /// Creates a read permission with key
605    #[inline]
606    pub fn read(key: impl Into<Vec<u8>>) -> Self {
607        Permission::new(PermissionType::Read, key)
608    }
609
610    /// Creates a write permission with key
611    #[inline]
612    pub fn write(key: impl Into<Vec<u8>>) -> Self {
613        Permission::new(PermissionType::Write, key)
614    }
615
616    /// Creates a read write permission with key
617    #[inline]
618    pub fn read_write(key: impl Into<Vec<u8>>) -> Self {
619        Permission::new(PermissionType::Readwrite, key)
620    }
621
622    /// Sets range end for the permission
623    #[inline]
624    pub fn with_range_end(mut self, range_end: impl Into<Vec<u8>>) -> Self {
625        self.inner.range_end = range_end.into();
626        self.with_prefix = false;
627        self.with_from_key = false;
628        self
629    }
630
631    /// Sets the permission with all keys >= key.
632    #[inline]
633    pub fn with_from_key(mut self) -> Self {
634        self.with_from_key = true;
635        self.with_prefix = false;
636        self
637    }
638
639    /// Sets the permission with all keys prefixed with key.
640    #[inline]
641    pub fn with_prefix(mut self) -> Self {
642        self.with_prefix = true;
643        self.with_from_key = false;
644        self
645    }
646
647    /// Sets the permission with all keys.
648    #[inline]
649    pub fn with_all_keys(mut self) -> Self {
650        self.inner.key.clear();
651        self.with_from_key()
652    }
653
654    /// The key in bytes. An empty key is not allowed.
655    #[inline]
656    pub fn key(&self) -> &[u8] {
657        &self.inner.key
658    }
659
660    /// The range end in bytes. maybe empty
661    #[inline]
662    pub fn range_end(&self) -> &[u8] {
663        &self.inner.range_end
664    }
665
666    /// The key in string. An empty key is not allowed.
667    #[inline]
668    pub fn key_str(&self) -> Result<&str> {
669        std::str::from_utf8(self.key()).map_err(From::from)
670    }
671
672    /// The key in string. An empty key is not allowed.
673    ///
674    /// # Safety
675    /// This function is unsafe because it does not check that the bytes of the key are valid UTF-8.
676    /// If this constraint is violated, undefined behavior results,
677    /// as the rest of Rust assumes that [`&str`]s are valid UTF-8.
678    #[inline]
679    pub unsafe fn key_str_unchecked(&self) -> &str {
680        std::str::from_utf8_unchecked(self.key())
681    }
682
683    /// The range end in string.
684    #[inline]
685    pub fn range_end_str(&self) -> Result<&str> {
686        std::str::from_utf8(self.range_end()).map_err(From::from)
687    }
688
689    /// The range end in string.
690    ///
691    /// # Safety
692    /// This function is unsafe because it does not check that the bytes of the key are valid UTF-8.
693    /// If this constraint is violated, undefined behavior results,
694    /// as the rest of Rust assumes that [`&str`]s are valid UTF-8.
695    #[inline]
696    pub unsafe fn range_end_str_unchecked(&self) -> &str {
697        std::str::from_utf8_unchecked(self.key())
698    }
699
700    /// Gets the operation type of permission.
701    #[inline]
702    pub const fn get_type(&self) -> i32 {
703        self.inner.perm_type
704    }
705
706    /// Indicates whether permission is with keys >= key.
707    #[inline]
708    pub const fn is_from_key(&self) -> bool {
709        self.with_from_key
710    }
711
712    /// Indicates whether permission is with all keys prefixed with key.
713    #[inline]
714    pub const fn is_prefix(&self) -> bool {
715        self.with_prefix
716    }
717}
718
719impl PartialEq for Permission {
720    #[inline]
721    fn eq(&self, other: &Self) -> bool {
722        if (self.with_prefix == other.with_prefix)
723            && (self.with_from_key == other.with_from_key)
724            && (self.inner.perm_type == other.inner.perm_type)
725        {
726            if self.inner.key == other.inner.key {
727                true
728            } else {
729                (self.inner.key.is_empty() && other.inner.key == [b'\0'])
730                    || (self.inner.key == [b'\0'] && other.inner.key.is_empty())
731            }
732        } else {
733            false
734        }
735    }
736}
737
738impl From<&PbPermission> for Permission {
739    #[inline]
740    fn from(src: &PbPermission) -> Self {
741        let mut perm = Permission {
742            inner: PbPermission {
743                perm_type: src.perm_type,
744                key: src.key.clone(),
745                range_end: src.range_end.clone(),
746            },
747            with_from_key: false,
748            with_prefix: false,
749        };
750
751        if perm.inner.range_end == [b'\0'] {
752            perm.with_from_key = true;
753        } else if !perm.inner.range_end.is_empty() {
754            let prefix = get_prefix(&perm.inner.key);
755            if prefix == perm.inner.range_end {
756                perm.with_prefix = true;
757            }
758        }
759        perm
760    }
761}
762
763impl From<Permission> for PbPermission {
764    #[inline]
765    fn from(mut perm: Permission) -> Self {
766        let mut key_range = KeyRange::new();
767        key_range.with_key(perm.inner.key);
768        key_range.with_range(perm.inner.range_end);
769        if perm.with_prefix {
770            key_range.with_prefix();
771        } else if perm.with_from_key {
772            key_range.with_from_key();
773        }
774        let (key, range_end) = key_range.build();
775        perm.inner.key = key;
776        perm.inner.range_end = range_end;
777        perm.inner
778    }
779}
780
781/// Response for get role operation.
782#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
783#[derive(Debug, Clone)]
784#[repr(transparent)]
785pub struct RoleGetResponse(PbAuthRoleGetResponse);
786
787impl RoleGetResponse {
788    /// Creates a new `RoleGetResponse` from pb role get response.
789    #[inline]
790    const fn new(resp: PbAuthRoleGetResponse) -> Self {
791        Self(resp)
792    }
793
794    /// Gets response header.
795    #[inline]
796    pub fn header(&self) -> Option<&ResponseHeader> {
797        self.0.header.as_ref().map(From::from)
798    }
799
800    /// Takes the header out of the response, leaving a [`None`] in its place.
801    #[inline]
802    pub fn take_header(&mut self) -> Option<ResponseHeader> {
803        self.0.header.take().map(ResponseHeader::new)
804    }
805
806    /// The list of permissions by the `Get` request.
807    #[inline]
808    pub fn permissions(&self) -> Vec<Permission> {
809        let mut perms = Vec::new();
810        for p in &self.0.perm {
811            perms.push(p.into());
812        }
813        perms
814    }
815}
816
817/// Options for list role operation.
818use PbAuthRoleListRequest as AuthRoleListOptions;
819
820/// Response for list role operation.
821#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
822#[derive(Debug, Clone)]
823#[repr(transparent)]
824pub struct RoleListResponse(PbAuthRoleListResponse);
825
826impl RoleListResponse {
827    /// Creates a new `RoleListResponse` from pb role list response.
828    #[inline]
829    const fn new(resp: PbAuthRoleListResponse) -> Self {
830        Self(resp)
831    }
832
833    /// Gets response header.
834    #[inline]
835    pub fn header(&self) -> Option<&ResponseHeader> {
836        self.0.header.as_ref().map(From::from)
837    }
838
839    /// Takes the header out of the response, leaving a [`None`] in its place.
840    #[inline]
841    pub fn take_header(&mut self) -> Option<ResponseHeader> {
842        self.0.header.take().map(ResponseHeader::new)
843    }
844
845    /// Gets roles in response.
846    #[inline]
847    pub fn roles(&self) -> &[String] {
848        self.0.roles.as_slice()
849    }
850}
851
852/// Options for grant role permission operation.
853#[derive(Debug, Default, Clone)]
854#[repr(transparent)]
855pub struct RoleGrantPermissionOptions(PbAuthRoleGrantPermissionRequest);
856
857impl RoleGrantPermissionOptions {
858    /// Creates a "RoleGrantPermissionOptions" to grant role permission
859    #[inline]
860    pub fn new(name: String, perm: Permission) -> Self {
861        Self(PbAuthRoleGrantPermissionRequest {
862            name,
863            perm: Some(perm.into()),
864        })
865    }
866}
867
868impl From<RoleGrantPermissionOptions> for PbAuthRoleGrantPermissionRequest {
869    #[inline]
870    fn from(options: RoleGrantPermissionOptions) -> Self {
871        options.0
872    }
873}
874
875impl IntoRequest<PbAuthRoleGrantPermissionRequest> for RoleGrantPermissionOptions {
876    #[inline]
877    fn into_request(self) -> Request<PbAuthRoleGrantPermissionRequest> {
878        Request::new(self.into())
879    }
880}
881
882/// Response for grant role permission operation.
883#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
884#[derive(Debug, Clone)]
885#[repr(transparent)]
886pub struct RoleGrantPermissionResponse(PbAuthRoleGrantPermissionResponse);
887
888impl RoleGrantPermissionResponse {
889    /// Creates a new `RoleGrantPermissionResponse` from pb role grant permission response.
890    #[inline]
891    const fn new(resp: PbAuthRoleGrantPermissionResponse) -> Self {
892        Self(resp)
893    }
894
895    /// Gets response header.
896    #[inline]
897    pub fn header(&self) -> Option<&ResponseHeader> {
898        self.0.header.as_ref().map(From::from)
899    }
900
901    /// Takes the header out of the response, leaving a [`None`] in its place.
902    #[inline]
903    pub fn take_header(&mut self) -> Option<ResponseHeader> {
904        self.0.header.take().map(ResponseHeader::new)
905    }
906}
907
908/// Options for grant role permission operation.
909#[derive(Debug, Default, Clone)]
910pub struct RoleRevokePermissionOptions {
911    req: PbAuthRoleRevokePermissionRequest,
912    key_range: KeyRange,
913}
914
915impl RoleRevokePermissionOptions {
916    /// Create a new `RoleRevokePermissionOption` from pb role revoke permission.
917    #[inline]
918    pub const fn new() -> Self {
919        Self {
920            req: PbAuthRoleRevokePermissionRequest {
921                role: String::new(),
922                key: Vec::new(),
923                range_end: Vec::new(),
924            },
925            key_range: KeyRange::new(),
926        }
927    }
928
929    /// Sets name.
930    #[inline]
931    fn with_name(mut self, name: String) -> Self {
932        self.req.role = name;
933        self
934    }
935
936    /// Sets key.
937    #[inline]
938    fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
939        self.key_range.with_key(key);
940        self
941    }
942
943    /// Specifies the range end.
944    /// `end_key` must be lexicographically greater than start key.
945    #[inline]
946    pub fn with_range_end(mut self, range_end: impl Into<Vec<u8>>) -> Self {
947        self.key_range.with_range(range_end);
948        self
949    }
950
951    /// Sets all keys prefixed with key.
952    #[inline]
953    pub fn with_prefix(mut self) -> Self {
954        self.key_range.with_prefix();
955        self
956    }
957
958    /// Sets all keys >= key.
959    #[inline]
960    pub fn with_from_key(mut self) -> Self {
961        self.key_range.with_from_key();
962        self
963    }
964
965    /// Sets all keys.
966    #[inline]
967    pub fn with_all_keys(mut self) -> Self {
968        self.key_range.with_all_keys();
969        self
970    }
971}
972
973impl From<RoleRevokePermissionOptions> for PbAuthRoleRevokePermissionRequest {
974    #[inline]
975    fn from(mut option: RoleRevokePermissionOptions) -> Self {
976        let (key, range_end) = option.key_range.build();
977        option.req.key = key;
978        option.req.range_end = range_end;
979        option.req
980    }
981}
982
983impl IntoRequest<PbAuthRoleRevokePermissionRequest> for RoleRevokePermissionOptions {
984    #[inline]
985    fn into_request(self) -> Request<PbAuthRoleRevokePermissionRequest> {
986        Request::new(self.into())
987    }
988}
989
990/// Response for revoke role permission operation.
991#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
992#[derive(Debug, Clone)]
993#[repr(transparent)]
994pub struct RoleRevokePermissionResponse(PbAuthRoleRevokePermissionResponse);
995
996impl RoleRevokePermissionResponse {
997    /// Creates a new `RoleRevokePermissionResponse` from pb role revoke permission response.
998    #[inline]
999    const fn new(resp: PbAuthRoleRevokePermissionResponse) -> Self {
1000        Self(resp)
1001    }
1002
1003    /// Gets response header.
1004    #[inline]
1005    pub fn header(&self) -> Option<&ResponseHeader> {
1006        self.0.header.as_ref().map(From::from)
1007    }
1008
1009    /// Takes the header out of the response, leaving a [`None`] in its place.
1010    #[inline]
1011    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1012        self.0.header.take().map(ResponseHeader::new)
1013    }
1014}
1015
1016/// Options for `UserAdd` operation.
1017#[derive(Debug, Default, Clone)]
1018#[repr(transparent)]
1019pub struct UserAddOptions(PbAuthUserAddRequest);
1020
1021impl UserAddOptions {
1022    /// Creates a `UserAddOptions`.
1023    #[inline]
1024    pub const fn new() -> Self {
1025        Self(PbAuthUserAddRequest {
1026            name: String::new(),
1027            password: String::new(),
1028            options: Some(PbUserAddOptions { no_password: false }),
1029        })
1030    }
1031
1032    /// Set name.
1033    #[inline]
1034    fn with_name(mut self, name: impl Into<String>) -> Self {
1035        self.0.name = name.into();
1036        self
1037    }
1038
1039    /// Set password.
1040    #[inline]
1041    fn with_pwd(mut self, password: impl Into<String>) -> Self {
1042        self.0.password = password.into();
1043        self
1044    }
1045
1046    /// Set no password.
1047    #[inline]
1048    pub const fn with_no_pwd(mut self) -> Self {
1049        self.0.options = Some(PbUserAddOptions { no_password: true });
1050        self
1051    }
1052}
1053
1054impl From<UserAddOptions> for PbAuthUserAddRequest {
1055    #[inline]
1056    fn from(options: UserAddOptions) -> Self {
1057        options.0
1058    }
1059}
1060
1061impl IntoRequest<PbAuthUserAddRequest> for UserAddOptions {
1062    #[inline]
1063    fn into_request(self) -> Request<PbAuthUserAddRequest> {
1064        Request::new(self.into())
1065    }
1066}
1067
1068/// Response for use add operation.
1069#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1070#[derive(Debug, Clone)]
1071#[repr(transparent)]
1072pub struct UserAddResponse(PbAuthUserAddResponse);
1073
1074impl UserAddResponse {
1075    /// Creates a new `UserAddReqResponse` from pb user add response.
1076    #[inline]
1077    const fn new(resp: PbAuthUserAddResponse) -> Self {
1078        Self(resp)
1079    }
1080
1081    /// Gets response header.
1082    #[inline]
1083    pub fn header(&self) -> Option<&ResponseHeader> {
1084        self.0.header.as_ref().map(From::from)
1085    }
1086
1087    /// Takes the header out of the response, leaving a [`None`] in its place.
1088    #[inline]
1089    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1090        self.0.header.take().map(ResponseHeader::new)
1091    }
1092}
1093
1094/// Options for get user operation.
1095#[derive(Debug, Default, Clone)]
1096#[repr(transparent)]
1097pub struct UserGetOptions(PbAuthUserGetRequest);
1098
1099impl UserGetOptions {
1100    /// Creates a `UserGetOptions` to get user.
1101    #[inline]
1102    pub fn new(name: String) -> Self {
1103        Self(PbAuthUserGetRequest { name })
1104    }
1105}
1106
1107impl From<UserGetOptions> for PbAuthUserGetRequest {
1108    #[inline]
1109    fn from(options: UserGetOptions) -> Self {
1110        options.0
1111    }
1112}
1113
1114impl IntoRequest<PbAuthUserGetRequest> for UserGetOptions {
1115    #[inline]
1116    fn into_request(self) -> Request<PbAuthUserGetRequest> {
1117        Request::new(self.into())
1118    }
1119}
1120
1121/// Response for get user operation.
1122#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1123#[derive(Debug, Clone)]
1124#[repr(transparent)]
1125pub struct UserGetResponse(PbAuthUserGetResponse);
1126
1127impl UserGetResponse {
1128    /// Creates a new `UserGetResponse` from pb user get response.
1129    #[inline]
1130    const fn new(resp: PbAuthUserGetResponse) -> Self {
1131        Self(resp)
1132    }
1133
1134    /// Gets response header.
1135    #[inline]
1136    pub fn header(&self) -> Option<&ResponseHeader> {
1137        self.0.header.as_ref().map(From::from)
1138    }
1139
1140    /// Takes the header out of the response, leaving a [`None`] in its place.
1141    #[inline]
1142    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1143        self.0.header.take().map(ResponseHeader::new)
1144    }
1145
1146    /// Gets roles of the user in response.
1147    #[inline]
1148    pub fn roles(&self) -> &[String] {
1149        &self.0.roles
1150    }
1151}
1152
1153/// Options for list user operation.
1154use PbAuthUserListRequest as AuthUserListOptions;
1155
1156/// Response for list user operation.
1157#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1158#[derive(Debug, Clone)]
1159#[repr(transparent)]
1160pub struct UserListResponse(PbAuthUserListResponse);
1161
1162impl UserListResponse {
1163    /// Creates a new `UserListResponse` from pb user list response.
1164    #[inline]
1165    const fn new(resp: PbAuthUserListResponse) -> Self {
1166        Self(resp)
1167    }
1168
1169    /// Gets response header.
1170    #[inline]
1171    pub fn header(&self) -> Option<&ResponseHeader> {
1172        self.0.header.as_ref().map(From::from)
1173    }
1174
1175    /// Takes the header out of the response, leaving a [`None`] in its place.
1176    #[inline]
1177    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1178        self.0.header.take().map(ResponseHeader::new)
1179    }
1180
1181    /// Gets users in response.
1182    #[inline]
1183    pub fn users(&self) -> &[String] {
1184        &self.0.users
1185    }
1186}
1187
1188/// Options for delete user operation.
1189#[derive(Debug, Default, Clone)]
1190#[repr(transparent)]
1191pub struct UserDeleteOptions(PbAuthUserDeleteRequest);
1192
1193impl UserDeleteOptions {
1194    /// Creates a `UserDeleteOptions` to delete user.
1195    #[inline]
1196    pub fn new(name: String) -> Self {
1197        Self(PbAuthUserDeleteRequest { name })
1198    }
1199}
1200
1201impl From<UserDeleteOptions> for PbAuthUserDeleteRequest {
1202    #[inline]
1203    fn from(options: UserDeleteOptions) -> Self {
1204        options.0
1205    }
1206}
1207
1208impl IntoRequest<PbAuthUserDeleteRequest> for UserDeleteOptions {
1209    #[inline]
1210    fn into_request(self) -> Request<PbAuthUserDeleteRequest> {
1211        Request::new(self.into())
1212    }
1213}
1214
1215/// Response for delete user operation.
1216#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1217#[derive(Debug, Clone)]
1218#[repr(transparent)]
1219pub struct UserDeleteResponse(PbAuthUserDeleteResponse);
1220
1221impl UserDeleteResponse {
1222    /// Creates a new `UserDeleteResponse` from pb user delete response.
1223    #[inline]
1224    const fn new(resp: PbAuthUserDeleteResponse) -> Self {
1225        Self(resp)
1226    }
1227
1228    /// Gets response header.
1229    #[inline]
1230    pub fn header(&self) -> Option<&ResponseHeader> {
1231        self.0.header.as_ref().map(From::from)
1232    }
1233
1234    /// Takes the header out of the response, leaving a [`None`] in its place.
1235    #[inline]
1236    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1237        self.0.header.take().map(ResponseHeader::new)
1238    }
1239}
1240
1241/// Options for change user's password operation.
1242#[derive(Debug, Default, Clone)]
1243#[repr(transparent)]
1244pub struct UserChangePasswordOptions(PbAuthUserChangePasswordRequest);
1245
1246impl UserChangePasswordOptions {
1247    /// Creates a `UserChangePasswordOptions` to change user's password.
1248    #[inline]
1249    pub fn new(name: String, new_password: String) -> Self {
1250        Self(PbAuthUserChangePasswordRequest {
1251            name,
1252            password: new_password,
1253        })
1254    }
1255}
1256
1257impl From<UserChangePasswordOptions> for PbAuthUserChangePasswordRequest {
1258    #[inline]
1259    fn from(options: UserChangePasswordOptions) -> Self {
1260        options.0
1261    }
1262}
1263
1264impl IntoRequest<PbAuthUserChangePasswordRequest> for UserChangePasswordOptions {
1265    #[inline]
1266    fn into_request(self) -> Request<PbAuthUserChangePasswordRequest> {
1267        Request::new(self.into())
1268    }
1269}
1270
1271/// Response for change user's password operation.
1272#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1273#[derive(Debug, Clone)]
1274#[repr(transparent)]
1275pub struct UserChangePasswordResponse(PbAuthUserChangePasswordResponse);
1276
1277impl UserChangePasswordResponse {
1278    /// Creates a new `UserChangePasswordResponse` from pb user change password response.
1279    #[inline]
1280    const fn new(resp: PbAuthUserChangePasswordResponse) -> Self {
1281        Self(resp)
1282    }
1283
1284    /// Gets response header.
1285    #[inline]
1286    pub fn header(&self) -> Option<&ResponseHeader> {
1287        self.0.header.as_ref().map(From::from)
1288    }
1289
1290    /// Takes the header out of the response, leaving a [`None`] in its place.
1291    #[inline]
1292    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1293        self.0.header.take().map(ResponseHeader::new)
1294    }
1295}
1296
1297/// Options for grant role for an user operation.
1298#[derive(Debug, Default, Clone)]
1299#[repr(transparent)]
1300pub struct UserGrantRoleOptions(PbAuthUserGrantRoleRequest);
1301
1302impl UserGrantRoleOptions {
1303    /// Creates a `UserGrantRoleOptions` to grant role for an user.
1304    #[inline]
1305    pub fn new(name: String, role: String) -> Self {
1306        Self(PbAuthUserGrantRoleRequest { user: name, role })
1307    }
1308}
1309
1310impl From<UserGrantRoleOptions> for PbAuthUserGrantRoleRequest {
1311    #[inline]
1312    fn from(options: UserGrantRoleOptions) -> Self {
1313        options.0
1314    }
1315}
1316
1317impl IntoRequest<PbAuthUserGrantRoleRequest> for UserGrantRoleOptions {
1318    #[inline]
1319    fn into_request(self) -> Request<PbAuthUserGrantRoleRequest> {
1320        Request::new(self.into())
1321    }
1322}
1323
1324/// Response for grant role for an user operation.
1325#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1326#[derive(Debug, Clone)]
1327#[repr(transparent)]
1328pub struct UserGrantRoleResponse(PbAuthUserGrantRoleResponse);
1329
1330impl UserGrantRoleResponse {
1331    /// Creates a new `UserGrantRoleResponse` from pb user grant role response.
1332    #[inline]
1333    const fn new(resp: PbAuthUserGrantRoleResponse) -> Self {
1334        Self(resp)
1335    }
1336
1337    /// Gets response header.
1338    #[inline]
1339    pub fn header(&self) -> Option<&ResponseHeader> {
1340        self.0.header.as_ref().map(From::from)
1341    }
1342
1343    /// Takes the header out of the response, leaving a [`None`] in its place.
1344    #[inline]
1345    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1346        self.0.header.take().map(ResponseHeader::new)
1347    }
1348}
1349
1350/// Options for revoke role for an user operation.
1351#[derive(Debug, Default, Clone)]
1352#[repr(transparent)]
1353pub struct UserRevokeRoleOptions(PbAuthUserRevokeRoleRequest);
1354
1355impl UserRevokeRoleOptions {
1356    /// Creates a `UserRevokeRoleOptions` to revoke role for an user.
1357    #[inline]
1358    pub fn new(name: String, role: String) -> Self {
1359        Self(PbAuthUserRevokeRoleRequest { name, role })
1360    }
1361}
1362
1363impl From<UserRevokeRoleOptions> for PbAuthUserRevokeRoleRequest {
1364    #[inline]
1365    fn from(options: UserRevokeRoleOptions) -> Self {
1366        options.0
1367    }
1368}
1369
1370impl IntoRequest<PbAuthUserRevokeRoleRequest> for UserRevokeRoleOptions {
1371    #[inline]
1372    fn into_request(self) -> Request<PbAuthUserRevokeRoleRequest> {
1373        Request::new(self.into())
1374    }
1375}
1376
1377/// Response for revoke role for an user operation.
1378#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1379#[derive(Debug, Clone)]
1380#[repr(transparent)]
1381pub struct UserRevokeRoleResponse(PbAuthUserRevokeRoleResponse);
1382
1383impl UserRevokeRoleResponse {
1384    /// Creates a new `UserRevokeRoleResponse` from pb user revoke role response.
1385    #[inline]
1386    const fn new(resp: PbAuthUserRevokeRoleResponse) -> Self {
1387        Self(resp)
1388    }
1389
1390    /// Gets response header.
1391    #[inline]
1392    pub fn header(&self) -> Option<&ResponseHeader> {
1393        self.0.header.as_ref().map(From::from)
1394    }
1395
1396    /// Takes the header out of the response, leaving a [`None`] in its place.
1397    #[inline]
1398    pub fn take_header(&mut self) -> Option<ResponseHeader> {
1399        self.0.header.take().map(ResponseHeader::new)
1400    }
1401}