From 6b4e6bcebf1127f7b1444790580bb5b64f31c6e7 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Mon, 12 Dec 2016 21:41:23 +0530 Subject: [PATCH] Move LoginHandler into LoginServer which others embed (#3431) * Move LoginHandler into LoginServer which others embed * Add unit tests for loginServer --- cmd/lock-rpc-server.go | 20 +---------- cmd/login-server.go | 41 +++++++++++++++++++++++ cmd/login-server_test.go | 67 +++++++++++++++++++++++++++++++++++++ cmd/s3-peer-router.go | 2 ++ cmd/s3-peer-rpc-handlers.go | 20 ----------- cmd/storage-rpc-server.go | 22 +----------- 6 files changed, 112 insertions(+), 60 deletions(-) create mode 100644 cmd/login-server.go create mode 100644 cmd/login-server_test.go diff --git a/cmd/lock-rpc-server.go b/cmd/lock-rpc-server.go index 2b4a9e83c..5ee4a7312 100644 --- a/cmd/lock-rpc-server.go +++ b/cmd/lock-rpc-server.go @@ -34,6 +34,7 @@ const lockCheckValidityInterval = 2 * time.Minute // LockArgs besides lock name, holds Token and Timestamp for session // authentication and validation server restart. type LockArgs struct { + loginServer Name string Token string Timestamp time.Time @@ -125,25 +126,6 @@ func registerStorageLockers(mux *router.Router, lockServers []*lockServer) error /// Distributed lock handlers -// LoginHandler - handles LoginHandler RPC call. -func (l *lockServer) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) error { - jwt, err := newJWT(defaultInterNodeJWTExpiry, serverConfig.GetCredential()) - if err != nil { - return err - } - if err = jwt.Authenticate(args.Username, args.Password); err != nil { - return err - } - token, err := jwt.GenerateToken(args.Username) - if err != nil { - return err - } - reply.Token = token - reply.Timestamp = time.Now().UTC() - reply.ServerVersion = Version - return nil -} - // Lock - rpc handler for (single) write lock operation. func (l *lockServer) Lock(args *LockArgs, reply *bool) error { l.mutex.Lock() diff --git a/cmd/login-server.go b/cmd/login-server.go new file mode 100644 index 000000000..0de184100 --- /dev/null +++ b/cmd/login-server.go @@ -0,0 +1,41 @@ +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * 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 cmd + +import "time" + +type loginServer struct { +} + +// LoginHandler - Handles JWT based RPC logic. +func (b loginServer) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) error { + jwt, err := newJWT(defaultInterNodeJWTExpiry, serverConfig.GetCredential()) + if err != nil { + return err + } + if err = jwt.Authenticate(args.Username, args.Password); err != nil { + return err + } + token, err := jwt.GenerateToken(args.Username) + if err != nil { + return err + } + reply.Token = token + reply.Timestamp = time.Now().UTC() + reply.ServerVersion = Version + return nil +} diff --git a/cmd/login-server_test.go b/cmd/login-server_test.go new file mode 100644 index 000000000..a79e18371 --- /dev/null +++ b/cmd/login-server_test.go @@ -0,0 +1,67 @@ +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * 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 cmd + +import "testing" + +func TestLoginHandler(t *testing.T) { + rootPath, err := newTestConfig("us-east-1") + if err != nil { + t.Fatalf("Failed to create test config - %v", err) + } + defer removeAll(rootPath) + creds := serverConfig.GetCredential() + ls := loginServer{} + testCases := []struct { + args RPCLoginArgs + expectedErr error + }{ + // Valid username and password + { + args: RPCLoginArgs{Username: creds.AccessKeyID, Password: creds.SecretAccessKey}, + expectedErr: nil, + }, + // Invalid username length + { + args: RPCLoginArgs{Username: "aaa", Password: "minio123"}, + expectedErr: errInvalidAccessKeyLength, + }, + // Invalid password length + { + args: RPCLoginArgs{Username: "minio", Password: "aaa"}, + expectedErr: errInvalidSecretKeyLength, + }, + // Invalid username + { + args: RPCLoginArgs{Username: "aaaaa", Password: creds.SecretAccessKey}, + expectedErr: errInvalidAccessKeyID, + }, + // Invalid password + { + args: RPCLoginArgs{Username: creds.AccessKeyID, Password: "aaaaaaaa"}, + expectedErr: errAuthentication, + }, + } + for i, test := range testCases { + reply := RPCLoginReply{} + err := ls.LoginHandler(&test.args, &reply) + if err != test.expectedErr { + t.Errorf("Test %d: Expected error %v but received %v", + i+1, test.expectedErr, err) + } + } +} diff --git a/cmd/s3-peer-router.go b/cmd/s3-peer-router.go index b1c0e6681..e6575f967 100644 --- a/cmd/s3-peer-router.go +++ b/cmd/s3-peer-router.go @@ -27,11 +27,13 @@ const ( ) type s3PeerAPIHandlers struct { + loginServer bms BucketMetaState } func registerS3PeerRPCRouter(mux *router.Router) error { s3PeerHandlers := &s3PeerAPIHandlers{ + loginServer{}, &localBucketMetaState{ ObjectAPI: newObjectLayerFn, }, diff --git a/cmd/s3-peer-rpc-handlers.go b/cmd/s3-peer-rpc-handlers.go index a7f5bb82a..46b7d9611 100644 --- a/cmd/s3-peer-rpc-handlers.go +++ b/cmd/s3-peer-rpc-handlers.go @@ -16,26 +16,6 @@ package cmd -import "time" - -func (s3 *s3PeerAPIHandlers) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) error { - jwt, err := newJWT(defaultInterNodeJWTExpiry, serverConfig.GetCredential()) - if err != nil { - return err - } - if err = jwt.Authenticate(args.Username, args.Password); err != nil { - return err - } - token, err := jwt.GenerateToken(args.Username) - if err != nil { - return err - } - reply.Token = token - reply.ServerVersion = Version - reply.Timestamp = time.Now().UTC() - return nil -} - // SetBucketNotificationPeerArgs - Arguments collection to SetBucketNotificationPeer RPC // call type SetBucketNotificationPeerArgs struct { diff --git a/cmd/storage-rpc-server.go b/cmd/storage-rpc-server.go index 11658a299..66dfc294e 100644 --- a/cmd/storage-rpc-server.go +++ b/cmd/storage-rpc-server.go @@ -29,32 +29,12 @@ import ( // Storage server implements rpc primitives to facilitate exporting a // disk over a network. type storageServer struct { + loginServer storage StorageAPI path string timestamp time.Time } -/// Auth operations - -// Login - login handler. -func (s *storageServer) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) error { - jwt, err := newJWT(defaultInterNodeJWTExpiry, serverConfig.GetCredential()) - if err != nil { - return err - } - if err = jwt.Authenticate(args.Username, args.Password); err != nil { - return err - } - token, err := jwt.GenerateToken(args.Username) - if err != nil { - return err - } - reply.Token = token - reply.Timestamp = time.Now().UTC() - reply.ServerVersion = Version - return nil -} - /// Storage operations handlers. // DiskInfoHandler - disk info handler is rpc wrapper for DiskInfo operation.