21700: Install Bundler system-wide in Rails postinst
[arvados.git] / lib / controller / localdb / login_testuser_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package localdb
6
7 import (
8         "database/sql"
9
10         "git.arvados.org/arvados.git/lib/ctrlctx"
11         "git.arvados.org/arvados.git/sdk/go/arvados"
12         "git.arvados.org/arvados.git/sdk/go/arvadostest"
13         check "gopkg.in/check.v1"
14 )
15
16 var _ = check.Suite(&TestUserSuite{})
17
18 type TestUserSuite struct {
19         localdbSuite
20 }
21
22 func (s *TestUserSuite) SetUpTest(c *check.C) {
23         s.localdbSuite.SetUpTest(c)
24         s.cluster.Login.Test.Enable = true
25         s.cluster.Login.Test.Users = map[string]arvados.TestUser{
26                 "valid": {Email: "valid@example.com", Password: "v@l1d"},
27         }
28         s.localdb.loginController = &testLoginController{
29                 Cluster: s.cluster,
30                 Parent:  s.localdb,
31         }
32 }
33
34 func (s *TestUserSuite) TestLogin(c *check.C) {
35         for _, trial := range []struct {
36                 success  bool
37                 username string
38                 password string
39         }{
40                 {false, "foo", "bar"},
41                 {false, "", ""},
42                 {false, "valid", ""},
43                 {false, "", "v@l1d"},
44                 {true, "valid", "v@l1d"},
45                 {true, "valid@example.com", "v@l1d"},
46         } {
47                 c.Logf("=== %#v", trial)
48                 resp, err := s.localdb.UserAuthenticate(s.ctx, arvados.UserAuthenticateOptions{
49                         Username: trial.username,
50                         Password: trial.password,
51                 })
52                 if trial.success {
53                         c.Check(err, check.IsNil)
54                         c.Check(resp.APIToken, check.Not(check.Equals), "")
55                         c.Check(resp.UUID, check.Matches, `zzzzz-gj3su-.*`)
56                         c.Check(resp.Scopes, check.DeepEquals, []string{"all"})
57
58                         authinfo := getCallbackAuthInfo(c, s.railsSpy)
59                         c.Check(authinfo.Email, check.Equals, "valid@example.com")
60                         c.Check(authinfo.AlternateEmails, check.DeepEquals, []string(nil))
61                 } else {
62                         c.Check(err, check.ErrorMatches, `authentication failed.*`)
63                 }
64         }
65 }
66
67 func (s *TestUserSuite) TestLoginForm(c *check.C) {
68         resp, err := s.localdb.Login(s.ctx, arvados.LoginOptions{
69                 ReturnTo: "https://localhost:12345/example",
70         })
71         c.Check(err, check.IsNil)
72         c.Check(resp.HTML.String(), check.Matches, `(?ms).*<form method="POST".*`)
73         c.Check(resp.HTML.String(), check.Matches, `(?ms).*<input id="return_to" type="hidden" name="return_to" value="https://localhost:12345/example">.*`)
74 }
75
76 func (s *TestUserSuite) TestExpireTokenOnLogout(c *check.C) {
77         s.cluster.Login.TrustPrivateNetworks = true
78         returnTo := "https://[::1]:12345/logout"
79         for _, trial := range []struct {
80                 requestToken      string
81                 expiringTokenUUID string
82                 shouldExpireToken bool
83         }{
84                 // v2 token
85                 {arvadostest.ActiveTokenV2, arvadostest.ActiveTokenUUID, true},
86                 // v1 token
87                 {arvadostest.AdminToken, arvadostest.AdminTokenUUID, true},
88                 // inexistent v1 token -- logout shouldn't fail
89                 {"thisdoesntexistasatoken", "", false},
90                 // inexistent v2 token -- logout shouldn't fail
91                 {"v2/some-fake-uuid/thisdoesntexistasatoken", "", false},
92         } {
93                 c.Logf("=== %#v", trial)
94                 ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, trial.requestToken)
95
96                 var tokenUUID string
97                 var err error
98                 qry := `SELECT uuid FROM api_client_authorizations WHERE uuid=$1 AND (expires_at IS NULL OR expires_at > current_timestamp AT TIME ZONE 'UTC') LIMIT 1`
99
100                 if trial.shouldExpireToken {
101                         err = s.tx.QueryRowContext(ctx, qry, trial.expiringTokenUUID).Scan(&tokenUUID)
102                         c.Check(err, check.IsNil)
103                 }
104
105                 resp, err := s.localdb.Logout(ctx, arvados.LogoutOptions{
106                         ReturnTo: returnTo,
107                 })
108                 c.Check(err, check.IsNil)
109                 c.Check(resp.RedirectLocation, check.Equals, returnTo)
110
111                 if trial.shouldExpireToken {
112                         err = s.tx.QueryRowContext(ctx, qry, trial.expiringTokenUUID).Scan(&tokenUUID)
113                         c.Check(err, check.Equals, sql.ErrNoRows)
114                 }
115         }
116 }