package service import ( "context" "testing" "github.com/keys-pub/keys" "github.com/keys-pub/keys-ext/vault" "github.com/stretchr/testify/require" "google.golang.org/grpc/metadata" ) func TestAuthWithPassword(t *testing.T) { var err error env, closeFn := newEnv(t, "", "") defer closeFn() auth := newAuth(env) vlt := newTestVault(t) err = vlt.Open() require.NoError(t, err) defer vlt.Close() ctx := context.TODO() // Setup needed status, err := vlt.Status() require.NoError(t, err) require.Equal(t, vault.SetupNeeded, status) // Setup err = auth.setup(ctx, vlt, &AuthSetupRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) status, err = vlt.Status() require.NoError(t, err) require.Equal(t, vault.Locked, status) // Unlock token, err := auth.unlock(ctx, vlt, &AuthUnlockRequest{Secret: "password123", Type: PasswordAuth, Client: "test"}) require.NoError(t, err) require.NotEmpty(t, auth.tokens) require.NotEmpty(t, token) // Lock auth.lock(vlt) // Unlock with invalid password _, err = auth.unlock(ctx, vlt, &AuthUnlockRequest{Secret: "invalidpassword", Type: PasswordAuth, Client: "test"}) require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid password") require.Empty(t, auth.tokens) // Unlock token, err = auth.unlock(ctx, vlt, &AuthUnlockRequest{Secret: "password123", Type: PasswordAuth, Client: "test"}) require.NoError(t, err) require.NotEmpty(t, auth.tokens) require.NotEmpty(t, token) } func TestAuthorize(t *testing.T) { var err error env, closeFn := newEnv(t, "", "") defer closeFn() auth := newAuth(env) vlt := newTestVault(t) err = vlt.Open() require.NoError(t, err) defer vlt.Close() ctx := metadata.NewIncomingContext(context.TODO(), metadata.MD{}) err = auth.authorize(ctx, "/service.RPC/SomeMethod") require.EqualError(t, err, "rpc error: code = Unauthenticated desc = authorization missing") ctx2 := metadata.NewIncomingContext(context.TODO(), metadata.MD{ "authorization": []string{""}, }) err = auth.authorize(ctx2, "/service.RPC/SomeMethod") require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid token") ctx3 := metadata.NewIncomingContext(context.TODO(), metadata.MD{ "authorization": []string{"badtoken"}, }) err = auth.authorize(ctx3, "/service.RPC/SomeMethod") require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid token") // Setup err = auth.setup(ctx, vlt, &AuthSetupRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) token, err := auth.unlock(ctx, vlt, &AuthUnlockRequest{Secret: "password123", Type: PasswordAuth, Client: "test"}) require.NoError(t, err) require.NotEmpty(t, auth.tokens) require.NotEmpty(t, token) ctx4 := metadata.NewIncomingContext(context.TODO(), metadata.MD{ "authorization": []string{token}, }) err = auth.authorize(ctx4, "/service.RPC/SomeMethod") require.NoError(t, err) ctx5 := metadata.NewIncomingContext(context.TODO(), metadata.MD{ "authorization": []string{"badtoken"}, }) err = auth.authorize(ctx5, "/service.RPC/SomeMethod") require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid token") } func TestGenerateToken(t *testing.T) { token := generateToken() require.NotEmpty(t, token) } func TestAuthUnlockLock(t *testing.T) { env := newTestEnv(t) service, closeFn := newTestService(t, env) defer closeFn() ctx := context.TODO() // Setup/Unlock var err error password := "password123" _, err = service.AuthSetup(ctx, &AuthSetupRequest{ Secret: password, Type: PasswordAuth, }) require.NoError(t, err) _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: password, Type: PasswordAuth, Client: "test", }) require.NoError(t, err) // Unlock again _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: password, Type: PasswordAuth, Client: "test", }) require.NoError(t, err) testImportKey(t, service, alice) _, err = service.Sign(context.TODO(), &SignRequest{Data: []byte("test"), Signer: alice.ID().String()}) require.NoError(t, err) items, err := service.vault.Items() require.NoError(t, err) require.Equal(t, 1, len(items)) _, err = service.AuthLock(ctx, &AuthLockRequest{}) require.NoError(t, err) require.Empty(t, service.auth.tokens) _, err = service.Sign(context.TODO(), &SignRequest{Data: []byte("test"), Signer: alice.ID().String()}) require.EqualError(t, err, "vault is locked") } func TestPasswordChange(t *testing.T) { // vault.SetLogger(NewLogger(DebugLevel)) var err error env := newTestEnv(t) service, closeFn := newTestService(t, env) defer closeFn() ctx := context.TODO() _, err = service.AuthSetup(ctx, &AuthSetupRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: "password123", Type: PasswordAuth, Client: "test", }) require.NoError(t, err) // _, err = service.VaultSync(context.TODO(), &VaultSyncRequest{}) // require.NoError(t, err) _, err = service.AuthPasswordChange(ctx, &AuthPasswordChangeRequest{ Old: "invalid", New: "newpassword", }) require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid password") _, err = service.AuthPasswordChange(ctx, &AuthPasswordChangeRequest{ Old: "", New: "newpassword", }) require.EqualError(t, err, "empty password") _, err = service.AuthPasswordChange(ctx, &AuthPasswordChangeRequest{ Old: "password123", New: "password1234", }) require.NoError(t, err) _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: "password123", Type: PasswordAuth, Client: "test", }) require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid password") _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: "password1234", Type: PasswordAuth, Client: "test", }) require.NoError(t, err) } func TestUnlockMultipleClients(t *testing.T) { env := newTestEnv(t) service, closeFn := newTestService(t, env) defer closeFn() ctx := context.TODO() var err error password := "password123" _, err = service.AuthSetup(ctx, &AuthSetupRequest{ Secret: password, Type: PasswordAuth, }) require.NoError(t, err) // Unlock app app, err := service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: password, Type: PasswordAuth, Client: "app", }) require.NoError(t, err) // Unlock CLI cli, err := service.AuthUnlock(ctx, &AuthUnlockRequest{ Secret: password, Type: PasswordAuth, Client: "cli", }) require.NoError(t, err) // Check tokens err = service.auth.checkToken(app.AuthToken) require.NoError(t, err) err = service.auth.checkToken(cli.AuthToken) require.NoError(t, err) // Lock _, err = service.AuthLock(ctx, &AuthLockRequest{}) require.NoError(t, err) err = service.auth.checkToken(app.AuthToken) require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid token") err = service.auth.checkToken(cli.AuthToken) require.EqualError(t, err, "rpc error: code = Unauthenticated desc = invalid token") require.False(t, service.db.IsOpen()) } func TestAuthReset(t *testing.T) { var err error env := newTestEnv(t) service, closeFn := newTestService(t, env) defer closeFn() ctx := context.TODO() _, err = service.AuthSetup(ctx, &AuthSetupRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) _, err = service.KeyGenerate(ctx, &KeyGenerateRequest{Type: string(keys.EdX25519)}) require.NoError(t, err) keysResp, err := service.Keys(ctx, &KeysRequest{}) require.NoError(t, err) require.Equal(t, 1, len(keysResp.Keys)) _, err = service.AuthReset(ctx, &AuthResetRequest{AppName: service.env.AppName()}) require.EqualError(t, err, "failed to reset: auth is unlocked") _, err = service.AuthLock(ctx, &AuthLockRequest{}) require.NoError(t, err) _, err = service.AuthReset(ctx, &AuthResetRequest{AppName: "InvalidAppName"}) require.EqualError(t, err, "failed to reset: invalid app name") _, err = service.AuthReset(ctx, &AuthResetRequest{AppName: service.env.AppName()}) require.NoError(t, err) _, err = service.AuthSetup(ctx, &AuthSetupRequest{Secret: "password12345", Type: PasswordAuth}) require.NoError(t, err) _, err = service.AuthUnlock(ctx, &AuthUnlockRequest{Secret: "password12345", Type: PasswordAuth}) require.NoError(t, err) _, err = service.KeyGenerate(ctx, &KeyGenerateRequest{Type: string(keys.EdX25519)}) require.NoError(t, err) keysResp, err = service.Keys(ctx, &KeysRequest{}) require.NoError(t, err) require.Equal(t, 1, len(keysResp.Keys)) } func TestAuthSetupLocked(t *testing.T) { var err error env := newTestEnv(t) service, closeFn := newTestService(t, env) defer closeFn() ctx := context.TODO() _, err = service.AuthSetup(ctx, &AuthSetupRequest{Secret: "password123", Type: PasswordAuth}) require.NoError(t, err) _, err = service.KeyGenerate(ctx, &KeyGenerateRequest{Type: string(keys.EdX25519)}) require.EqualError(t, err, "vault is locked") }