blob: 382172b21bf59f54f29060c4625d419b174b9f2c [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001// Copyright 2016 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package clientv3
16
17import (
18 "context"
19 "fmt"
20 "strings"
21
22 "google.golang.org/grpc"
23
24 "go.etcd.io/etcd/api/v3/authpb"
25 pb "go.etcd.io/etcd/api/v3/etcdserverpb"
26)
27
28type (
29 AuthEnableResponse pb.AuthEnableResponse
30 AuthDisableResponse pb.AuthDisableResponse
31 AuthStatusResponse pb.AuthStatusResponse
32 AuthenticateResponse pb.AuthenticateResponse
33 AuthUserAddResponse pb.AuthUserAddResponse
34 AuthUserDeleteResponse pb.AuthUserDeleteResponse
35 AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse
36 AuthUserGrantRoleResponse pb.AuthUserGrantRoleResponse
37 AuthUserGetResponse pb.AuthUserGetResponse
38 AuthUserRevokeRoleResponse pb.AuthUserRevokeRoleResponse
39 AuthRoleAddResponse pb.AuthRoleAddResponse
40 AuthRoleGrantPermissionResponse pb.AuthRoleGrantPermissionResponse
41 AuthRoleGetResponse pb.AuthRoleGetResponse
42 AuthRoleRevokePermissionResponse pb.AuthRoleRevokePermissionResponse
43 AuthRoleDeleteResponse pb.AuthRoleDeleteResponse
44 AuthUserListResponse pb.AuthUserListResponse
45 AuthRoleListResponse pb.AuthRoleListResponse
46
47 PermissionType authpb.Permission_Type
48 Permission authpb.Permission
49)
50
51const (
52 PermRead = authpb.READ
53 PermWrite = authpb.WRITE
54 PermReadWrite = authpb.READWRITE
55)
56
57type UserAddOptions authpb.UserAddOptions
58
59type Auth interface {
60 // Authenticate login and get token
61 Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error)
62
63 // AuthEnable enables auth of an etcd cluster.
64 AuthEnable(ctx context.Context) (*AuthEnableResponse, error)
65
66 // AuthDisable disables auth of an etcd cluster.
67 AuthDisable(ctx context.Context) (*AuthDisableResponse, error)
68
69 // AuthStatus returns the status of auth of an etcd cluster.
70 AuthStatus(ctx context.Context) (*AuthStatusResponse, error)
71
72 // UserAdd adds a new user to an etcd cluster.
73 UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
74
75 // UserAddWithOptions adds a new user to an etcd cluster with some options.
76 UserAddWithOptions(ctx context.Context, name string, password string, opt *UserAddOptions) (*AuthUserAddResponse, error)
77
78 // UserDelete deletes a user from an etcd cluster.
79 UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error)
80
81 // UserChangePassword changes a password of a user.
82 UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error)
83
84 // UserGrantRole grants a role to a user.
85 UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error)
86
87 // UserGet gets a detailed information of a user.
88 UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error)
89
90 // UserList gets a list of all users.
91 UserList(ctx context.Context) (*AuthUserListResponse, error)
92
93 // UserRevokeRole revokes a role of a user.
94 UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error)
95
96 // RoleAdd adds a new role to an etcd cluster.
97 RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error)
98
99 // RoleGrantPermission grants a permission to a role.
100 RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error)
101
102 // RoleGet gets a detailed information of a role.
103 RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error)
104
105 // RoleList gets a list of all roles.
106 RoleList(ctx context.Context) (*AuthRoleListResponse, error)
107
108 // RoleRevokePermission revokes a permission from a role.
109 RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error)
110
111 // RoleDelete deletes a role.
112 RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error)
113}
114
115type authClient struct {
116 remote pb.AuthClient
117 callOpts []grpc.CallOption
118}
119
120func NewAuth(c *Client) Auth {
121 api := &authClient{remote: RetryAuthClient(c)}
122 if c != nil {
123 api.callOpts = c.callOpts
124 }
125 return api
126}
127
128func NewAuthFromAuthClient(remote pb.AuthClient, c *Client) Auth {
129 api := &authClient{remote: remote}
130 if c != nil {
131 api.callOpts = c.callOpts
132 }
133 return api
134}
135
136func (auth *authClient) Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) {
137 resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, auth.callOpts...)
138 return (*AuthenticateResponse)(resp), ContextError(ctx, err)
139}
140
141func (auth *authClient) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
142 resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...)
143 return (*AuthEnableResponse)(resp), ContextError(ctx, err)
144}
145
146func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
147 resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...)
148 return (*AuthDisableResponse)(resp), ContextError(ctx, err)
149}
150
151func (auth *authClient) AuthStatus(ctx context.Context) (*AuthStatusResponse, error) {
152 resp, err := auth.remote.AuthStatus(ctx, &pb.AuthStatusRequest{}, auth.callOpts...)
153 return (*AuthStatusResponse)(resp), ContextError(ctx, err)
154}
155
156func (auth *authClient) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
157 resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: &authpb.UserAddOptions{NoPassword: false}}, auth.callOpts...)
158 return (*AuthUserAddResponse)(resp), ContextError(ctx, err)
159}
160
161func (auth *authClient) UserAddWithOptions(ctx context.Context, name string, password string, options *UserAddOptions) (*AuthUserAddResponse, error) {
162 resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: (*authpb.UserAddOptions)(options)}, auth.callOpts...)
163 return (*AuthUserAddResponse)(resp), ContextError(ctx, err)
164}
165
166func (auth *authClient) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
167 resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...)
168 return (*AuthUserDeleteResponse)(resp), ContextError(ctx, err)
169}
170
171func (auth *authClient) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
172 resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...)
173 return (*AuthUserChangePasswordResponse)(resp), ContextError(ctx, err)
174}
175
176func (auth *authClient) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
177 resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...)
178 return (*AuthUserGrantRoleResponse)(resp), ContextError(ctx, err)
179}
180
181func (auth *authClient) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
182 resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...)
183 return (*AuthUserGetResponse)(resp), ContextError(ctx, err)
184}
185
186func (auth *authClient) UserList(ctx context.Context) (*AuthUserListResponse, error) {
187 resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...)
188 return (*AuthUserListResponse)(resp), ContextError(ctx, err)
189}
190
191func (auth *authClient) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
192 resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...)
193 return (*AuthUserRevokeRoleResponse)(resp), ContextError(ctx, err)
194}
195
196func (auth *authClient) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
197 resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...)
198 return (*AuthRoleAddResponse)(resp), ContextError(ctx, err)
199}
200
201func (auth *authClient) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
202 perm := &authpb.Permission{
203 Key: []byte(key),
204 RangeEnd: []byte(rangeEnd),
205 PermType: authpb.Permission_Type(permType),
206 }
207 resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, auth.callOpts...)
208 return (*AuthRoleGrantPermissionResponse)(resp), ContextError(ctx, err)
209}
210
211func (auth *authClient) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
212 resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...)
213 return (*AuthRoleGetResponse)(resp), ContextError(ctx, err)
214}
215
216func (auth *authClient) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
217 resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...)
218 return (*AuthRoleListResponse)(resp), ContextError(ctx, err)
219}
220
221func (auth *authClient) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
222 resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: []byte(key), RangeEnd: []byte(rangeEnd)}, auth.callOpts...)
223 return (*AuthRoleRevokePermissionResponse)(resp), ContextError(ctx, err)
224}
225
226func (auth *authClient) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
227 resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...)
228 return (*AuthRoleDeleteResponse)(resp), ContextError(ctx, err)
229}
230
231func StrToPermissionType(s string) (PermissionType, error) {
232 val, ok := authpb.Permission_Type_value[strings.ToUpper(s)]
233 if ok {
234 return PermissionType(val), nil
235 }
236 return PermissionType(-1), fmt.Errorf("invalid permission type: %s", s)
237}