Skip to main content

etcd_client/rpc/
auth.rs

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