mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #4917 from mitake/auth-user-delete
*: support deleting user in v3 auth
This commit is contained in:
commit
59bb65182a
@ -32,6 +32,7 @@ var (
|
||||
plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth")
|
||||
|
||||
ErrUserAlreadyExist = errors.New("auth: user already exists")
|
||||
ErrUserNotFound = errors.New("auth: user not found")
|
||||
)
|
||||
|
||||
type AuthStore interface {
|
||||
@ -43,6 +44,9 @@ type AuthStore interface {
|
||||
|
||||
// UserAdd adds a new user
|
||||
UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
||||
|
||||
// UserDelete deletes a user
|
||||
UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
||||
}
|
||||
|
||||
type authStore struct {
|
||||
@ -103,6 +107,23 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse,
|
||||
return &pb.AuthUserAddResponse{}, nil
|
||||
}
|
||||
|
||||
func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
|
||||
tx := as.be.BatchTx()
|
||||
tx.Lock()
|
||||
defer tx.Unlock()
|
||||
|
||||
_, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0)
|
||||
if len(vs) != 1 {
|
||||
return &pb.AuthUserDeleteResponse{}, ErrUserNotFound
|
||||
}
|
||||
|
||||
tx.UnsafeDelete(authUsersBucketName, []byte(r.Name))
|
||||
|
||||
plog.Noticef("deleted a user: %s", r.Name)
|
||||
|
||||
return &pb.AuthUserDeleteResponse{}, nil
|
||||
}
|
||||
|
||||
func NewAuthStore(be backend.Backend) *authStore {
|
||||
tx := be.BatchTx()
|
||||
tx.Lock()
|
||||
|
@ -21,8 +21,9 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
AuthEnableResponse pb.AuthEnableResponse
|
||||
AuthUserAddResponse pb.AuthUserAddResponse
|
||||
AuthEnableResponse pb.AuthEnableResponse
|
||||
AuthUserAddResponse pb.AuthUserAddResponse
|
||||
AuthUserDeleteResponse pb.AuthUserDeleteResponse
|
||||
)
|
||||
|
||||
type Auth interface {
|
||||
@ -31,6 +32,9 @@ type Auth interface {
|
||||
|
||||
// UserAdd adds a new user to an etcd cluster.
|
||||
UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
|
||||
|
||||
// UserDelete deletes a user from an etcd cluster.
|
||||
UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error)
|
||||
}
|
||||
|
||||
type auth struct {
|
||||
@ -58,3 +62,8 @@ func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*A
|
||||
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password})
|
||||
return (*AuthUserAddResponse)(resp), err
|
||||
}
|
||||
|
||||
func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
|
||||
resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name})
|
||||
return (*AuthUserDeleteResponse)(resp), err
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ func NewUserCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
ac.AddCommand(NewUserAddCommand())
|
||||
ac.AddCommand(NewUserDeleteCommand())
|
||||
|
||||
return ac
|
||||
}
|
||||
@ -51,6 +52,14 @@ func NewUserAddCommand() *cobra.Command {
|
||||
return &cmd
|
||||
}
|
||||
|
||||
func NewUserDeleteCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "delete <user name>",
|
||||
Short: "delete a user",
|
||||
Run: userDeleteCommandFunc,
|
||||
}
|
||||
}
|
||||
|
||||
// userAddCommandFunc executes the "user add" command.
|
||||
func userAddCommandFunc(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
@ -89,3 +98,15 @@ func userAddCommandFunc(cmd *cobra.Command, args []string) {
|
||||
ExitWithError(ExitError, err)
|
||||
}
|
||||
}
|
||||
|
||||
// userDeleteCommandFunc executes the "user delete" command.
|
||||
func userDeleteCommandFunc(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 1 {
|
||||
ExitWithError(ExitBadArgs, fmt.Errorf("user delete command requires user name as its argument."))
|
||||
}
|
||||
|
||||
_, err := mustClientFromCmd(cmd).Auth.UserDelete(context.TODO(), args[0])
|
||||
if err != nil {
|
||||
ExitWithError(ExitError, err)
|
||||
}
|
||||
}
|
||||
|
@ -80,8 +80,11 @@ func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*p
|
||||
}
|
||||
|
||||
func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
|
||||
plog.Info("not implemented yet")
|
||||
return nil, nil
|
||||
resp, err := as.authenticator.UserDelete(ctx, r)
|
||||
if err != nil {
|
||||
return nil, togRPCError(err)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
|
||||
|
@ -38,4 +38,5 @@ var (
|
||||
ErrRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large")
|
||||
|
||||
ErrUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists")
|
||||
ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found")
|
||||
)
|
||||
|
@ -39,6 +39,8 @@ func togRPCError(err error) error {
|
||||
return rpctypes.ErrNoSpace
|
||||
case auth.ErrUserAlreadyExist:
|
||||
return rpctypes.ErrUserAlreadyExist
|
||||
case auth.ErrUserNotFound:
|
||||
return rpctypes.ErrUserNotFound
|
||||
default:
|
||||
return grpc.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ type applierV3 interface {
|
||||
Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error)
|
||||
AuthEnable() (*pb.AuthEnableResponse, error)
|
||||
UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
||||
UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
||||
}
|
||||
|
||||
type applierV3backend struct {
|
||||
@ -84,6 +85,8 @@ func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult {
|
||||
ar.resp, ar.err = s.applyV3.AuthEnable()
|
||||
case r.AuthUserAdd != nil:
|
||||
ar.resp, ar.err = s.applyV3.UserAdd(r.AuthUserAdd)
|
||||
case r.AuthUserDelete != nil:
|
||||
ar.resp, ar.err = s.applyV3.UserDelete(r.AuthUserDelete)
|
||||
default:
|
||||
panic("not implemented")
|
||||
}
|
||||
@ -475,6 +478,10 @@ func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddRes
|
||||
return a.s.AuthStore().UserAdd(r)
|
||||
}
|
||||
|
||||
func (a *applierV3backend) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
|
||||
return a.s.AuthStore().UserDelete(r)
|
||||
}
|
||||
|
||||
type quotaApplierV3 struct {
|
||||
applierV3
|
||||
q Quota
|
||||
|
@ -22,18 +22,19 @@ var _ = math.Inf
|
||||
// An InternalRaftRequest is the union of all requests which can be
|
||||
// sent via raft.
|
||||
type InternalRaftRequest struct {
|
||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"`
|
||||
Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"`
|
||||
Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"`
|
||||
DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"`
|
||||
Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"`
|
||||
Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"`
|
||||
LeaseCreate *LeaseCreateRequest `protobuf:"bytes,8,opt,name=lease_create" json:"lease_create,omitempty"`
|
||||
LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"`
|
||||
AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"`
|
||||
AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add" json:"auth_user_add,omitempty"`
|
||||
Alarm *AlarmRequest `protobuf:"bytes,12,opt,name=alarm" json:"alarm,omitempty"`
|
||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"`
|
||||
Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"`
|
||||
Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"`
|
||||
DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"`
|
||||
Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"`
|
||||
Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"`
|
||||
LeaseCreate *LeaseCreateRequest `protobuf:"bytes,8,opt,name=lease_create" json:"lease_create,omitempty"`
|
||||
LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"`
|
||||
AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"`
|
||||
AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add" json:"auth_user_add,omitempty"`
|
||||
AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,12,opt,name=auth_user_delete" json:"auth_user_delete,omitempty"`
|
||||
Alarm *AlarmRequest `protobuf:"bytes,13,opt,name=alarm" json:"alarm,omitempty"`
|
||||
}
|
||||
|
||||
func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} }
|
||||
@ -171,16 +172,26 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) {
|
||||
}
|
||||
i += n10
|
||||
}
|
||||
if m.Alarm != nil {
|
||||
if m.AuthUserDelete != nil {
|
||||
data[i] = 0x62
|
||||
i++
|
||||
i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size()))
|
||||
n11, err := m.Alarm.MarshalTo(data[i:])
|
||||
i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserDelete.Size()))
|
||||
n11, err := m.AuthUserDelete.MarshalTo(data[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n11
|
||||
}
|
||||
if m.Alarm != nil {
|
||||
data[i] = 0x6a
|
||||
i++
|
||||
i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size()))
|
||||
n12, err := m.Alarm.MarshalTo(data[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n12
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@ -275,6 +286,10 @@ func (m *InternalRaftRequest) Size() (n int) {
|
||||
l = m.AuthUserAdd.Size()
|
||||
n += 1 + l + sovRaftInternal(uint64(l))
|
||||
}
|
||||
if m.AuthUserDelete != nil {
|
||||
l = m.AuthUserDelete.Size()
|
||||
n += 1 + l + sovRaftInternal(uint64(l))
|
||||
}
|
||||
if m.Alarm != nil {
|
||||
l = m.Alarm.Size()
|
||||
n += 1 + l + sovRaftInternal(uint64(l))
|
||||
@ -680,6 +695,39 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 12:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AuthUserDelete", 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.AuthUserDelete == nil {
|
||||
m.AuthUserDelete = &AuthUserDeleteRequest{}
|
||||
}
|
||||
if err := m.AuthUserDelete.Unmarshal(data[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 13:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ message InternalRaftRequest {
|
||||
|
||||
AuthEnableRequest auth_enable = 10;
|
||||
AuthUserAddRequest auth_user_add = 11;
|
||||
AuthUserDeleteRequest auth_user_delete = 12;
|
||||
|
||||
AlarmRequest alarm = 12;
|
||||
AlarmRequest alarm = 13;
|
||||
}
|
||||
|
||||
message EmptyResponse {
|
||||
|
@ -1287,6 +1287,7 @@ func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m)
|
||||
func (*AuthUserGetRequest) ProtoMessage() {}
|
||||
|
||||
type AuthUserDeleteRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} }
|
||||
@ -4465,6 +4466,12 @@ func (m *AuthUserDeleteRequest) MarshalTo(data []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Name) > 0 {
|
||||
data[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintRpc(data, i, uint64(len(m.Name)))
|
||||
i += copy(data[i:], m.Name)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
@ -5751,6 +5758,10 @@ func (m *AuthUserGetRequest) Size() (n int) {
|
||||
func (m *AuthUserDeleteRequest) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Name)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovRpc(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -10706,6 +10717,35 @@ func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error {
|
||||
return fmt.Errorf("proto: AuthUserDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
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
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipRpc(data[iNdEx:])
|
||||
|
@ -489,6 +489,7 @@ message AuthUserGetRequest {
|
||||
}
|
||||
|
||||
message AuthUserDeleteRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message AuthUserChangePasswordRequest {
|
||||
|
@ -54,6 +54,7 @@ type Lessor interface {
|
||||
type Authenticator interface {
|
||||
AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error)
|
||||
UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
|
||||
UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
|
||||
}
|
||||
|
||||
func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
|
||||
@ -191,6 +192,14 @@ func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb
|
||||
return result.resp.(*pb.AuthUserAddResponse), result.err
|
||||
}
|
||||
|
||||
func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
|
||||
result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.resp.(*pb.AuthUserDeleteResponse), result.err
|
||||
}
|
||||
|
||||
func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) {
|
||||
r.ID = s.reqIDGen.Next()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user