1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
15 "git.arvados.org/arvados.git/lib/controller/rpc"
16 "git.arvados.org/arvados.git/sdk/go/arvados"
17 "git.arvados.org/arvados.git/sdk/go/arvadostest"
18 check "gopkg.in/check.v1"
21 var _ = check.Suite(&UserSuite{})
23 type UserSuite struct {
27 func (s *UserSuite) TestLoginClusterUserList(c *check.C) {
28 s.cluster.ClusterID = "local"
29 s.cluster.Login.LoginCluster = "zzzzz"
30 s.fed = New(s.cluster)
31 s.addDirectRemote(c, "zzzzz", rpc.NewConn("zzzzz", &url.URL{Scheme: "https", Host: os.Getenv("ARVADOS_API_HOST")}, true, rpc.PassthroughTokenProvider))
33 for _, updateFail := range []bool{false, true} {
34 for _, opts := range []arvados.ListOptions{
35 {Offset: 0, Limit: -1, Select: nil},
36 {Offset: 0, Limit: math.MaxInt64, Select: nil},
37 {Offset: 1, Limit: 1, Select: nil},
38 {Offset: 0, Limit: 2, Select: []string{"uuid"}},
39 {Offset: 0, Limit: 2, Select: []string{"uuid", "email"}},
41 c.Logf("updateFail %v, opts %#v", updateFail, opts)
42 spy := arvadostest.NewProxy(c, s.cluster.Services.RailsAPI)
43 stub := &arvadostest.APIStub{Error: errors.New("local cluster failure")}
47 s.fed.local = rpc.NewConn(s.cluster.ClusterID, spy.URL, true, rpc.PassthroughTokenProvider)
49 userlist, err := s.fed.UserList(s.ctx, opts)
51 c.Logf("... UserList failed %q", err)
53 if updateFail && err == nil {
54 // All local updates fail, so the only
55 // cases expected to succeed are the
56 // ones with 0 results.
57 c.Check(userlist.Items, check.HasLen, 0)
58 c.Check(stub.Calls(nil), check.HasLen, 0)
59 } else if updateFail {
60 c.Logf("... err %#v", err)
61 calls := stub.Calls(stub.UserBatchUpdate)
62 if c.Check(calls, check.HasLen, 1) {
63 c.Logf("... stub.UserUpdate called with options: %#v", calls[0].Options)
64 shouldUpdate := map[string]bool{
72 // can't safely update locally
74 "identity_url": false,
79 if opts.Select != nil {
81 // fields (minus uuid)
83 for k := range shouldUpdate {
84 shouldUpdate[k] = false
86 for _, k := range opts.Select {
88 shouldUpdate[k] = true
93 for uuid = range calls[0].Options.(arvados.UserBatchUpdateOptions).Updates {
95 for k, shouldFind := range shouldUpdate {
96 _, found := calls[0].Options.(arvados.UserBatchUpdateOptions).Updates[uuid][k]
97 c.Check(found, check.Equals, shouldFind, check.Commentf("offending attr: %s", k))
102 for _, d := range spy.RequestDumps {
104 if strings.Contains(d, "PATCH /arvados/v1/users/batch") {
105 c.Check(d, check.Matches, `(?ms).*Authorization: Bearer `+arvadostest.SystemRootToken+`.*`)
109 c.Check(err, check.IsNil)
110 c.Check(updates, check.Equals, 1)
111 c.Logf("... response items %#v", userlist.Items)
117 // userAttrsCachedFromLoginCluster must have an entry for every field
118 // in the User struct.
119 func (s *UserSuite) TestUserAttrsUpdateWhitelist(c *check.C) {
120 buf, err := json.Marshal(&arvados.User{})
121 c.Assert(err, check.IsNil)
122 var allFields map[string]interface{}
123 err = json.Unmarshal(buf, &allFields)
124 c.Assert(err, check.IsNil)
125 for k := range allFields {
126 _, ok := userAttrsCachedFromLoginCluster[k]
127 c.Check(ok, check.Equals, true, check.Commentf("field name %q missing from userAttrsCachedFromLoginCluster", k))