1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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"
16 var _ = check.Suite(&TestUserSuite{})
18 type TestUserSuite struct {
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"},
28 s.localdb.loginController = &testLoginController{
34 func (s *TestUserSuite) TestLogin(c *check.C) {
35 for _, trial := range []struct {
40 {false, "foo", "bar"},
44 {true, "valid", "v@l1d"},
45 {true, "valid@example.com", "v@l1d"},
47 c.Logf("=== %#v", trial)
48 resp, err := s.localdb.UserAuthenticate(s.ctx, arvados.UserAuthenticateOptions{
49 Username: trial.username,
50 Password: trial.password,
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"})
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))
62 c.Check(err, check.ErrorMatches, `authentication failed.*`)
67 func (s *TestUserSuite) TestLoginForm(c *check.C) {
68 resp, err := s.localdb.Login(s.ctx, arvados.LoginOptions{
69 ReturnTo: "https://localhost:12345/example",
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">.*`)
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 {
81 expiringTokenUUID string
82 shouldExpireToken bool
85 {arvadostest.ActiveTokenV2, arvadostest.ActiveTokenUUID, true},
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},
93 c.Logf("=== %#v", trial)
94 ctx := ctrlctx.NewWithToken(s.ctx, s.cluster, trial.requestToken)
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`
100 if trial.shouldExpireToken {
101 err = s.tx.QueryRowContext(ctx, qry, trial.expiringTokenUUID).Scan(&tokenUUID)
102 c.Check(err, check.IsNil)
105 resp, err := s.localdb.Logout(ctx, arvados.LogoutOptions{
108 c.Check(err, check.IsNil)
109 c.Check(resp.RedirectLocation, check.Equals, returnTo)
111 if trial.shouldExpireToken {
112 err = s.tx.QueryRowContext(ctx, qry, trial.expiringTokenUUID).Scan(&tokenUUID)
113 c.Check(err, check.Equals, sql.ErrNoRows)