mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #5124 from mitake/auth-v3-authenticate
*: support authenticate in v3 auth
This commit is contained in:
commit
8684d96914
71
auth/simple_token.go
Normal file
71
auth/simple_token.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2016 Nippon Telegraph and Telephone Corporation.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package auth
|
||||||
|
|
||||||
|
// CAUTION: This randum number based token mechanism is only for testing purpose.
|
||||||
|
// JWT based mechanism will be added in the near future.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
defaultSimpleTokenLength = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
simpleTokens map[string]string // token -> user ID
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
simpleTokens = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genSimpleToken() (string, error) {
|
||||||
|
ret := make([]byte, defaultSimpleTokenLength)
|
||||||
|
|
||||||
|
for i := 0; i < defaultSimpleTokenLength; i++ {
|
||||||
|
bInt, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[i] = letters[bInt.Int64()]
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(ret), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genSimpleTokenForUser(userID string) (string, error) {
|
||||||
|
var token string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for {
|
||||||
|
// generating random numbers in RSM would't a good idea
|
||||||
|
token, err = genSimpleToken()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := simpleTokens[token]; !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
simpleTokens[token] = userID
|
||||||
|
return token, nil
|
||||||
|
}
|
@ -40,12 +40,19 @@ var (
|
|||||||
ErrUserNotFound = errors.New("auth: user not found")
|
ErrUserNotFound = errors.New("auth: user not found")
|
||||||
ErrRoleAlreadyExist = errors.New("auth: role already exists")
|
ErrRoleAlreadyExist = errors.New("auth: role already exists")
|
||||||
ErrRoleNotFound = errors.New("auth: role not found")
|
ErrRoleNotFound = errors.New("auth: role not found")
|
||||||
|
ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password")
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthStore interface {
|
type AuthStore interface {
|
||||||
// AuthEnable() turns on the authentication feature
|
// AuthEnable() turns on the authentication feature
|
||||||
AuthEnable()
|
AuthEnable()
|
||||||
|
|
||||||
|
// Authenticate() does authentication based on given user name and password,
|
||||||
|
// and returns a token for successful case.
|
||||||
|
// Note that the generated token is valid only for the member the client
|
||||||
|
// connected to within fixed time duration. Reauth is required after the duration.
|
||||||
|
Authenticate(name string, password string) (*pb.AuthenticateResponse, error)
|
||||||
|
|
||||||
// Recover recovers the state of auth store from the given backend
|
// Recover recovers the state of auth store from the given backend
|
||||||
Recover(b backend.Backend)
|
Recover(b backend.Backend)
|
||||||
|
|
||||||
@ -85,6 +92,38 @@ func (as *authStore) AuthEnable() {
|
|||||||
plog.Noticef("Authentication enabled")
|
plog.Noticef("Authentication enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (as *authStore) Authenticate(name string, password string) (*pb.AuthenticateResponse, error) {
|
||||||
|
tx := as.be.BatchTx()
|
||||||
|
tx.Lock()
|
||||||
|
defer tx.Unlock()
|
||||||
|
|
||||||
|
_, vs := tx.UnsafeRange(authUsersBucketName, []byte(name), nil, 0)
|
||||||
|
if len(vs) != 1 {
|
||||||
|
plog.Noticef("authentication failed, user %s doesn't exist", name)
|
||||||
|
return &pb.AuthenticateResponse{}, ErrAuthFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
user := &authpb.User{}
|
||||||
|
err := user.Unmarshal(vs[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil {
|
||||||
|
plog.Noticef("authentication failed, invalid password for user %s", name)
|
||||||
|
return &pb.AuthenticateResponse{}, ErrAuthFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := genSimpleTokenForUser(name)
|
||||||
|
if err != nil {
|
||||||
|
plog.Errorf("failed to generate simple token: %s", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
plog.Infof("authorized %s, token is %s", name, token)
|
||||||
|
return &pb.AuthenticateResponse{Token: token}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (as *authStore) Recover(be backend.Backend) {
|
func (as *authStore) Recover(be backend.Backend) {
|
||||||
as.be = be
|
as.be = be
|
||||||
// TODO(mitake): recovery process
|
// TODO(mitake): recovery process
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
AuthEnableResponse pb.AuthEnableResponse
|
AuthEnableResponse pb.AuthEnableResponse
|
||||||
|
AuthenticateResponse pb.AuthenticateResponse
|
||||||
AuthUserAddResponse pb.AuthUserAddResponse
|
AuthUserAddResponse pb.AuthUserAddResponse
|
||||||
AuthUserDeleteResponse pb.AuthUserDeleteResponse
|
AuthUserDeleteResponse pb.AuthUserDeleteResponse
|
||||||
AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse
|
AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse
|
||||||
@ -46,6 +47,9 @@ type Auth interface {
|
|||||||
// AuthEnable enables auth of an etcd cluster.
|
// AuthEnable enables auth of an etcd cluster.
|
||||||
AuthEnable(ctx context.Context) (*AuthEnableResponse, error)
|
AuthEnable(ctx context.Context) (*AuthEnableResponse, error)
|
||||||
|
|
||||||
|
// Authenticate does authenticate with given user name and password.
|
||||||
|
Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error)
|
||||||
|
|
||||||
// UserAdd adds a new user to an etcd cluster.
|
// UserAdd adds a new user to an etcd cluster.
|
||||||
UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
|
UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
|
||||||
|
|
||||||
@ -86,6 +90,11 @@ func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
|
|||||||
return (*AuthEnableResponse)(resp), err
|
return (*AuthEnableResponse)(resp), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (auth *auth) Authenticate(ctx context.Context, name string, password string) (*AuthenticateResponse, error) {
|
||||||
|
resp, err := auth.remote.Authenticate(ctx, &pb.AuthenticateRequest{Name: name, Password: password})
|
||||||
|
return (*AuthenticateResponse)(resp), err
|
||||||
|
}
|
||||||
|
|
||||||
func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
|
func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
|
||||||
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password})
|
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password})
|
||||||
return (*AuthUserAddResponse)(resp), err
|
return (*AuthUserAddResponse)(resp), err
|
||||||
|
@ -42,8 +42,11 @@ func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
|
func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
|
||||||
plog.Info("not implemented yet")
|
resp, err := as.authenticator.Authenticate(ctx, r)
|
||||||
return nil, nil
|
if err != nil {
|
||||||
|
return nil, togRPCError(err)
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
|
func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
|
||||||
|
@ -41,4 +41,5 @@ var (
|
|||||||
ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found")
|
ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found")
|
||||||
ErrRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists")
|
ErrRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists")
|
||||||
ErrRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found")
|
ErrRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found")
|
||||||
|
ErrAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password")
|
||||||
)
|
)
|
||||||
|
@ -45,6 +45,8 @@ func togRPCError(err error) error {
|
|||||||
return rpctypes.ErrRoleAlreadyExist
|
return rpctypes.ErrRoleAlreadyExist
|
||||||
case auth.ErrRoleNotFound:
|
case auth.ErrRoleNotFound:
|
||||||
return rpctypes.ErrRoleNotFound
|
return rpctypes.ErrRoleNotFound
|
||||||
|
case auth.ErrAuthFailed:
|
||||||
|
return rpctypes.ErrAuthFailed
|
||||||
default:
|
default:
|
||||||
return grpc.Errorf(codes.Internal, err.Error())
|
return grpc.Errorf(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ type applierV3 interface {
|
|||||||
LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
|
LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
|
||||||
Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error)
|
Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error)
|
||||||
AuthEnable() (*pb.AuthEnableResponse, error)
|
AuthEnable() (*pb.AuthEnableResponse, error)
|
||||||
|
Authenticate(r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error)
|
||||||
UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
||||||
UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
||||||
UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
|
UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
|
||||||
@ -87,6 +88,8 @@ func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult {
|
|||||||
ar.resp, ar.err = s.applyV3.Alarm(r.Alarm)
|
ar.resp, ar.err = s.applyV3.Alarm(r.Alarm)
|
||||||
case r.AuthEnable != nil:
|
case r.AuthEnable != nil:
|
||||||
ar.resp, ar.err = s.applyV3.AuthEnable()
|
ar.resp, ar.err = s.applyV3.AuthEnable()
|
||||||
|
case r.Authenticate != nil:
|
||||||
|
ar.resp, ar.err = s.applyV3.Authenticate(r.Authenticate)
|
||||||
case r.AuthUserAdd != nil:
|
case r.AuthUserAdd != nil:
|
||||||
ar.resp, ar.err = s.applyV3.UserAdd(r.AuthUserAdd)
|
ar.resp, ar.err = s.applyV3.UserAdd(r.AuthUserAdd)
|
||||||
case r.AuthUserDelete != nil:
|
case r.AuthUserDelete != nil:
|
||||||
@ -490,6 +493,10 @@ func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) {
|
|||||||
return &pb.AuthEnableResponse{}, nil
|
return &pb.AuthEnableResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *applierV3backend) Authenticate(r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
|
||||||
|
return a.s.AuthStore().Authenticate(r.Name, r.Password)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
|
func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
|
||||||
return a.s.AuthStore().UserAdd(r)
|
return a.s.AuthStore().UserAdd(r)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ type InternalRaftRequest struct {
|
|||||||
AuthUserGrant *AuthUserGrantRequest `protobuf:"bytes,14,opt,name=auth_user_grant" json:"auth_user_grant,omitempty"`
|
AuthUserGrant *AuthUserGrantRequest `protobuf:"bytes,14,opt,name=auth_user_grant" json:"auth_user_grant,omitempty"`
|
||||||
AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,15,opt,name=auth_role_add" json:"auth_role_add,omitempty"`
|
AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,15,opt,name=auth_role_add" json:"auth_role_add,omitempty"`
|
||||||
AuthRoleGrant *AuthRoleGrantRequest `protobuf:"bytes,16,opt,name=auth_role_grant" json:"auth_role_grant,omitempty"`
|
AuthRoleGrant *AuthRoleGrantRequest `protobuf:"bytes,16,opt,name=auth_role_grant" json:"auth_role_grant,omitempty"`
|
||||||
Alarm *AlarmRequest `protobuf:"bytes,17,opt,name=alarm" json:"alarm,omitempty"`
|
Authenticate *AuthenticateRequest `protobuf:"bytes,17,opt,name=authenticate" json:"authenticate,omitempty"`
|
||||||
|
Alarm *AlarmRequest `protobuf:"bytes,18,opt,name=alarm" json:"alarm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} }
|
func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} }
|
||||||
@ -228,18 +229,30 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
i += n15
|
i += n15
|
||||||
}
|
}
|
||||||
if m.Alarm != nil {
|
if m.Authenticate != nil {
|
||||||
data[i] = 0x8a
|
data[i] = 0x8a
|
||||||
i++
|
i++
|
||||||
data[i] = 0x1
|
data[i] = 0x1
|
||||||
i++
|
i++
|
||||||
i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size()))
|
i = encodeVarintRaftInternal(data, i, uint64(m.Authenticate.Size()))
|
||||||
n16, err := m.Alarm.MarshalTo(data[i:])
|
n16, err := m.Authenticate.MarshalTo(data[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n16
|
i += n16
|
||||||
}
|
}
|
||||||
|
if m.Alarm != nil {
|
||||||
|
data[i] = 0x92
|
||||||
|
i++
|
||||||
|
data[i] = 0x1
|
||||||
|
i++
|
||||||
|
i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size()))
|
||||||
|
n17, err := m.Alarm.MarshalTo(data[i:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i += n17
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,6 +367,10 @@ func (m *InternalRaftRequest) Size() (n int) {
|
|||||||
l = m.AuthRoleGrant.Size()
|
l = m.AuthRoleGrant.Size()
|
||||||
n += 2 + l + sovRaftInternal(uint64(l))
|
n += 2 + l + sovRaftInternal(uint64(l))
|
||||||
}
|
}
|
||||||
|
if m.Authenticate != nil {
|
||||||
|
l = m.Authenticate.Size()
|
||||||
|
n += 2 + l + sovRaftInternal(uint64(l))
|
||||||
|
}
|
||||||
if m.Alarm != nil {
|
if m.Alarm != nil {
|
||||||
l = m.Alarm.Size()
|
l = m.Alarm.Size()
|
||||||
n += 2 + l + sovRaftInternal(uint64(l))
|
n += 2 + l + sovRaftInternal(uint64(l))
|
||||||
@ -924,6 +941,39 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
|
|||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 17:
|
case 17:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Authenticate", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRaftInternal
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthRaftInternal
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if m.Authenticate == nil {
|
||||||
|
m.Authenticate = &AuthenticateRequest{}
|
||||||
|
}
|
||||||
|
if err := m.Authenticate.Unmarshal(data[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 18:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,9 @@ message InternalRaftRequest {
|
|||||||
AuthUserGrantRequest auth_user_grant = 14;
|
AuthUserGrantRequest auth_user_grant = 14;
|
||||||
AuthRoleAddRequest auth_role_add = 15;
|
AuthRoleAddRequest auth_role_add = 15;
|
||||||
AuthRoleGrantRequest auth_role_grant = 16;
|
AuthRoleGrantRequest auth_role_grant = 16;
|
||||||
|
AuthenticateRequest authenticate = 17;
|
||||||
|
|
||||||
AlarmRequest alarm = 17;
|
AlarmRequest alarm = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EmptyResponse {
|
message EmptyResponse {
|
||||||
|
@ -1374,6 +1374,8 @@ func (m *AuthDisableRequest) String() string { return proto.CompactTextString(m)
|
|||||||
func (*AuthDisableRequest) ProtoMessage() {}
|
func (*AuthDisableRequest) ProtoMessage() {}
|
||||||
|
|
||||||
type AuthenticateRequest struct {
|
type AuthenticateRequest struct {
|
||||||
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
|
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} }
|
func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} }
|
||||||
@ -1514,6 +1516,8 @@ func (m *AuthDisableResponse) GetHeader() *ResponseHeader {
|
|||||||
|
|
||||||
type AuthenticateResponse struct {
|
type AuthenticateResponse struct {
|
||||||
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
||||||
|
// token is an authorized token that can be used in succeeding RPCs
|
||||||
|
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} }
|
func (m *AuthenticateResponse) Reset() { *m = AuthenticateResponse{} }
|
||||||
@ -4755,6 +4759,18 @@ func (m *AuthenticateRequest) MarshalTo(data []byte) (int, error) {
|
|||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
if len(m.Name) > 0 {
|
||||||
|
data[i] = 0xa
|
||||||
|
i++
|
||||||
|
i = encodeVarintRpc(data, i, uint64(len(m.Name)))
|
||||||
|
i += copy(data[i:], m.Name)
|
||||||
|
}
|
||||||
|
if len(m.Password) > 0 {
|
||||||
|
data[i] = 0x12
|
||||||
|
i++
|
||||||
|
i = encodeVarintRpc(data, i, uint64(len(m.Password)))
|
||||||
|
i += copy(data[i:], m.Password)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5101,6 +5117,12 @@ func (m *AuthenticateResponse) MarshalTo(data []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
i += n35
|
i += n35
|
||||||
}
|
}
|
||||||
|
if len(m.Token) > 0 {
|
||||||
|
data[i] = 0x12
|
||||||
|
i++
|
||||||
|
i = encodeVarintRpc(data, i, uint64(len(m.Token)))
|
||||||
|
i += copy(data[i:], m.Token)
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6187,6 +6209,14 @@ func (m *AuthDisableRequest) Size() (n int) {
|
|||||||
func (m *AuthenticateRequest) Size() (n int) {
|
func (m *AuthenticateRequest) Size() (n int) {
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
l = len(m.Name)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRpc(uint64(l))
|
||||||
|
}
|
||||||
|
l = len(m.Password)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRpc(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6323,6 +6353,10 @@ func (m *AuthenticateResponse) Size() (n int) {
|
|||||||
l = m.Header.Size()
|
l = m.Header.Size()
|
||||||
n += 1 + l + sovRpc(uint64(l))
|
n += 1 + l + sovRpc(uint64(l))
|
||||||
}
|
}
|
||||||
|
l = len(m.Token)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRpc(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11393,6 +11427,64 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error {
|
|||||||
return fmt.Errorf("proto: AuthenticateRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
return fmt.Errorf("proto: AuthenticateRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
}
|
}
|
||||||
switch fieldNum {
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRpc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Name = string(data[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRpc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Password = string(data[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipRpc(data[iNdEx:])
|
skippy, err := skipRpc(data[iNdEx:])
|
||||||
@ -12486,6 +12578,35 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 2:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRpc
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRpc
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.Token = string(data[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipRpc(data[iNdEx:])
|
skippy, err := skipRpc(data[iNdEx:])
|
||||||
|
@ -559,6 +559,8 @@ message AuthDisableRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message AuthenticateRequest {
|
message AuthenticateRequest {
|
||||||
|
string name = 1;
|
||||||
|
string password = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AuthUserAddRequest {
|
message AuthUserAddRequest {
|
||||||
@ -622,6 +624,8 @@ message AuthDisableResponse {
|
|||||||
|
|
||||||
message AuthenticateResponse {
|
message AuthenticateResponse {
|
||||||
ResponseHeader header = 1;
|
ResponseHeader header = 1;
|
||||||
|
// token is an authorized token that can be used in succeeding RPCs
|
||||||
|
string token = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AuthUserAddResponse {
|
message AuthUserAddResponse {
|
||||||
|
@ -53,6 +53,7 @@ type Lessor interface {
|
|||||||
|
|
||||||
type Authenticator interface {
|
type Authenticator interface {
|
||||||
AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error)
|
AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error)
|
||||||
|
Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error)
|
||||||
UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
||||||
UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
||||||
UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
|
UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
|
||||||
@ -212,6 +213,14 @@ func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*
|
|||||||
return result.resp.(*pb.AuthEnableResponse), result.err
|
return result.resp.(*pb.AuthEnableResponse), result.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
|
||||||
|
result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Authenticate: r})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result.resp.(*pb.AuthenticateResponse), result.err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
|
func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
|
||||||
result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r})
|
result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user