1// 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 "go.etcd.io/etcd/api/v3/authpb" 23 pb "go.etcd.io/etcd/api/v3/etcdserverpb" 24 "google.golang.org/grpc" 25) 26 27type ( 28 AuthEnableResponse pb.AuthEnableResponse 29 AuthDisableResponse pb.AuthDisableResponse 30 AuthStatusResponse pb.AuthStatusResponse 31 AuthenticateResponse pb.AuthenticateResponse 32 AuthUserAddResponse pb.AuthUserAddResponse 33 AuthUserDeleteResponse pb.AuthUserDeleteResponse 34 AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse 35 AuthUserGrantRoleResponse pb.AuthUserGrantRoleResponse 36 AuthUserGetResponse pb.AuthUserGetResponse 37 AuthUserRevokeRoleResponse pb.AuthUserRevokeRoleResponse 38 AuthRoleAddResponse pb.AuthRoleAddResponse 39 AuthRoleGrantPermissionResponse pb.AuthRoleGrantPermissionResponse 40 AuthRoleGetResponse pb.AuthRoleGetResponse 41 AuthRoleRevokePermissionResponse pb.AuthRoleRevokePermissionResponse 42 AuthRoleDeleteResponse pb.AuthRoleDeleteResponse 43 AuthUserListResponse pb.AuthUserListResponse 44 AuthRoleListResponse pb.AuthRoleListResponse 45 46 PermissionType authpb.Permission_Type 47 Permission authpb.Permission 48) 49 50const ( 51 PermRead = authpb.READ 52 PermWrite = authpb.WRITE 53 PermReadWrite = authpb.READWRITE 54) 55 56type UserAddOptions authpb.UserAddOptions 57 58type Auth interface { 59 // Authenticate login and get token 60 Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) 61 62 // AuthEnable enables auth of an etcd cluster. 63 AuthEnable(ctx context.Context) (*AuthEnableResponse, error) 64 65 // AuthDisable disables auth of an etcd cluster. 66 AuthDisable(ctx context.Context) (*AuthDisableResponse, error) 67 68 // AuthStatus returns the status of auth of an etcd cluster. 69 AuthStatus(ctx context.Context) (*AuthStatusResponse, error) 70 71 // UserAdd adds a new user to an etcd cluster. 72 UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) 73 74 // UserAddWithOptions adds a new user to an etcd cluster with some options. 75 UserAddWithOptions(ctx context.Context, name string, password string, opt *UserAddOptions) (*AuthUserAddResponse, error) 76 77 // UserDelete deletes a user from an etcd cluster. 78 UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) 79 80 // UserChangePassword changes a password of a user. 81 UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) 82 83 // UserGrantRole grants a role to a user. 84 UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) 85 86 // UserGet gets a detailed information of a user. 87 UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) 88 89 // UserList gets a list of all users. 90 UserList(ctx context.Context) (*AuthUserListResponse, error) 91 92 // UserRevokeRole revokes a role of a user. 93 UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) 94 95 // RoleAdd adds a new role to an etcd cluster. 96 RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) 97 98 // RoleGrantPermission grants a permission to a role. 99 RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) 100 101 // RoleGet gets a detailed information of a role. 102 RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) 103 104 // RoleList gets a list of all roles. 105 RoleList(ctx context.Context) (*AuthRoleListResponse, error) 106 107 // RoleRevokePermission revokes a permission from a role. 108 RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) 109 110 // RoleDelete deletes a role. 111 RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) 112} 113 114type authClient struct { 115 remote pb.AuthClient 116 callOpts []grpc.CallOption 117} 118 119func NewAuth(c *Client) Auth { 120 api := &authClient{remote: RetryAuthClient(c)} 121 if c != nil { 122 api.callOpts = c.callOpts 123 } 124 return api 125} 126 127func NewAuthFromAuthClient(remote pb.AuthClient, c *Client) Auth { 128 api := &authClient{remote: remote} 129 if c != nil { 130 api.callOpts = c.callOpts 131 } 132 return api 133} 134 135func (auth *authClient) Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) { 136 resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password}, auth.callOpts...) 137 return (*AuthenticateResponse)(resp), toErr(ctx, err) 138} 139 140func (auth *authClient) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { 141 resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...) 142 return (*AuthEnableResponse)(resp), toErr(ctx, err) 143} 144 145func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) { 146 resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...) 147 return (*AuthDisableResponse)(resp), toErr(ctx, err) 148} 149 150func (auth *authClient) AuthStatus(ctx context.Context) (*AuthStatusResponse, error) { 151 resp, err := auth.remote.AuthStatus(ctx, &pb.AuthStatusRequest{}, auth.callOpts...) 152 return (*AuthStatusResponse)(resp), toErr(ctx, err) 153} 154 155func (auth *authClient) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) { 156 resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: &authpb.UserAddOptions{NoPassword: false}}, auth.callOpts...) 157 return (*AuthUserAddResponse)(resp), toErr(ctx, err) 158} 159 160func (auth *authClient) UserAddWithOptions(ctx context.Context, name string, password string, options *UserAddOptions) (*AuthUserAddResponse, error) { 161 resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: (*authpb.UserAddOptions)(options)}, auth.callOpts...) 162 return (*AuthUserAddResponse)(resp), toErr(ctx, err) 163} 164 165func (auth *authClient) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) { 166 resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...) 167 return (*AuthUserDeleteResponse)(resp), toErr(ctx, err) 168} 169 170func (auth *authClient) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) { 171 resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...) 172 return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err) 173} 174 175func (auth *authClient) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) { 176 resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...) 177 return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err) 178} 179 180func (auth *authClient) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) { 181 resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...) 182 return (*AuthUserGetResponse)(resp), toErr(ctx, err) 183} 184 185func (auth *authClient) UserList(ctx context.Context) (*AuthUserListResponse, error) { 186 resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...) 187 return (*AuthUserListResponse)(resp), toErr(ctx, err) 188} 189 190func (auth *authClient) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) { 191 resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...) 192 return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err) 193} 194 195func (auth *authClient) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) { 196 resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...) 197 return (*AuthRoleAddResponse)(resp), toErr(ctx, err) 198} 199 200func (auth *authClient) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) { 201 perm := &authpb.Permission{ 202 Key: []byte(key), 203 RangeEnd: []byte(rangeEnd), 204 PermType: authpb.Permission_Type(permType), 205 } 206 resp, err := auth.remote.RoleGrantPermission(ctx, &pb.AuthRoleGrantPermissionRequest{Name: name, Perm: perm}, auth.callOpts...) 207 return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err) 208} 209 210func (auth *authClient) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) { 211 resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...) 212 return (*AuthRoleGetResponse)(resp), toErr(ctx, err) 213} 214 215func (auth *authClient) RoleList(ctx context.Context) (*AuthRoleListResponse, error) { 216 resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...) 217 return (*AuthRoleListResponse)(resp), toErr(ctx, err) 218} 219 220func (auth *authClient) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) { 221 resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: []byte(key), RangeEnd: []byte(rangeEnd)}, auth.callOpts...) 222 return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err) 223} 224 225func (auth *authClient) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) { 226 resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...) 227 return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err) 228} 229 230func StrToPermissionType(s string) (PermissionType, error) { 231 val, ok := authpb.Permission_Type_value[strings.ToUpper(s)] 232 if ok { 233 return PermissionType(val), nil 234 } 235 return PermissionType(-1), fmt.Errorf("invalid permission type: %s", s) 236} 237