github.com/stolowski/snapd@v0.0.0-20210407085831-115137ce5a22/store/userinfo_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package store_test 21 22 import ( 23 "fmt" 24 "net/http" 25 "net/http/httptest" 26 "os" 27 "time" 28 29 "gopkg.in/check.v1" 30 "gopkg.in/retry.v1" 31 32 "github.com/snapcore/snapd/logger" 33 "github.com/snapcore/snapd/store" 34 "github.com/snapcore/snapd/testutil" 35 ) 36 37 type userInfoSuite struct { 38 testutil.BaseTest 39 40 store *store.Store 41 restoreLogger func() 42 } 43 44 var _ = check.Suite(&userInfoSuite{}) 45 46 // obtained via: 47 // `curl https://login.staging.ubuntu.com/api/v2/keys/mvo@ubuntu.com` 48 // `curl https://login.staging.ubuntu.com/api/v2/keys/xDPXBdB` 49 var mockServerJSON = `{ 50 "username": "mvo", 51 "ssh_keys": [ 52 "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAqwsTkky+laeukWyGFmtiAQUFgjD+wKYuRtOj11gjTe3qUNDgMR54W8IUELZ6NwNWs2wium+jQZLY4vlsDq4PkYK8J2qgjRZURCKp4JbjbVNSg2WO7vDtl+0FIC1GaCdglRVWffrwKN1RLlwqBCVXi01nnTk3+hEpWddjqoTXMwM= egon@top", 53 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKBFmfD1KNULZv35907+ArIfxdGGzF1XCQj287AgK7k5GWcEdnUQfkSUHRZ4cNOqshY6W3CyDzVAmaDmeB9A7qpmsVlQp2D8y253+F2NMm1bcDdT3weG5vxkdF5qdx99gRMwDYJ4WZgIryrCAOqDLKmoSEuyuh1Zil9pDGPh/grf+EgXzDFnntgE8XJVKIldsbUplCmycSNtk47PtJATJ8q5v2dIazlxwmxKfarXS7x805u4ElrZ2h3JMCOOfL1k3sJbYc4JbZ6zB8DAhSsZ79KrStn3DE+gULmPJjM0HEbtouegZpE5wcHldoo4Oi78uNrwtv1lWp4AnK/Xwm3bl/ egon@bod\r\n" 54 ], 55 "openid_identifier": "xDPXBdB" 56 }` 57 58 var mockServerNoSSHJSON = `{ 59 "username": "mvo", 60 "openid_identifier": "xDPXBdB" 61 }` 62 63 func (t *userInfoSuite) SetUpTest(c *check.C) { 64 t.BaseTest.SetUpTest(c) 65 66 _, t.restoreLogger = logger.MockLogger() 67 t.store = store.New(nil, nil) 68 69 store.MockDefaultRetryStrategy(&t.BaseTest, retry.LimitCount(6, retry.LimitTime(1*time.Second, 70 retry.Exponential{ 71 Initial: 1 * time.Millisecond, 72 Factor: 1.1, 73 }, 74 ))) 75 } 76 77 func (t *userInfoSuite) TearDownTest(c *check.C) { 78 t.BaseTest.TearDownTest(c) 79 80 t.restoreLogger() 81 } 82 83 func (s *userInfoSuite) redirectToTestSSO(handler func(http.ResponseWriter, *http.Request)) { 84 server := httptest.NewServer(http.HandlerFunc(handler)) 85 s.BaseTest.AddCleanup(func() { server.Close() }) 86 os.Setenv("SNAPPY_FORCE_SSO_URL", server.URL+"/api/v2") 87 s.BaseTest.AddCleanup(func() { os.Unsetenv("SNAPPY_FORCE_SSO_URL") }) 88 } 89 90 func (s *userInfoSuite) TestCreateUserNoSSHKeys(c *check.C) { 91 n := 0 92 s.redirectToTestSSO(func(w http.ResponseWriter, r *http.Request) { 93 switch n { 94 case 0, 1: 95 w.WriteHeader(500) // force retry of the request 96 case 2: 97 c.Check(r.Method, check.Equals, "GET") 98 c.Check(r.URL.Path, check.Equals, "/api/v2/keys/popper@lse.ac.uk") 99 fmt.Fprintln(w, mockServerNoSSHJSON) 100 default: 101 c.Fatalf("expected to get 1 requests, now on %d", n+1) 102 } 103 104 n++ 105 }) 106 107 info, err := s.store.UserInfo("popper@lse.ac.uk") 108 c.Assert(err, check.IsNil) 109 c.Assert(n, check.Equals, 3) // number of requests after retries 110 c.Check(info.Username, check.Equals, "mvo") 111 c.Check(info.OpenIDIdentifier, check.Equals, "xDPXBdB") 112 c.Check(info.SSHKeys, check.HasLen, 0) 113 } 114 115 func (s *userInfoSuite) TestCreateUser(c *check.C) { 116 n := 0 117 s.redirectToTestSSO(func(w http.ResponseWriter, r *http.Request) { 118 switch n { 119 case 0, 1: 120 w.WriteHeader(500) // force retry of the request 121 case 2: 122 c.Check(r.Method, check.Equals, "GET") 123 c.Check(r.URL.Path, check.Equals, "/api/v2/keys/popper@lse.ac.uk") 124 fmt.Fprintln(w, mockServerJSON) 125 default: 126 c.Fatalf("expected to get 1 requests, now on %d", n+1) 127 } 128 129 n++ 130 }) 131 132 info, err := s.store.UserInfo("popper@lse.ac.uk") 133 c.Assert(err, check.IsNil) 134 c.Assert(n, check.Equals, 3) // number of requests after retries 135 c.Check(info.Username, check.Equals, "mvo") 136 c.Check(info.OpenIDIdentifier, check.Equals, "xDPXBdB") 137 c.Check(info.SSHKeys, check.DeepEquals, []string{"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAqwsTkky+laeukWyGFmtiAQUFgjD+wKYuRtOj11gjTe3qUNDgMR54W8IUELZ6NwNWs2wium+jQZLY4vlsDq4PkYK8J2qgjRZURCKp4JbjbVNSg2WO7vDtl+0FIC1GaCdglRVWffrwKN1RLlwqBCVXi01nnTk3+hEpWddjqoTXMwM= egon@top", 138 "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKBFmfD1KNULZv35907+ArIfxdGGzF1XCQj287AgK7k5GWcEdnUQfkSUHRZ4cNOqshY6W3CyDzVAmaDmeB9A7qpmsVlQp2D8y253+F2NMm1bcDdT3weG5vxkdF5qdx99gRMwDYJ4WZgIryrCAOqDLKmoSEuyuh1Zil9pDGPh/grf+EgXzDFnntgE8XJVKIldsbUplCmycSNtk47PtJATJ8q5v2dIazlxwmxKfarXS7x805u4ElrZ2h3JMCOOfL1k3sJbYc4JbZ6zB8DAhSsZ79KrStn3DE+gULmPJjM0HEbtouegZpE5wcHldoo4Oi78uNrwtv1lWp4AnK/Xwm3bl/ egon@bod\r\n"}) 139 } 140 141 func (s *userInfoSuite) TestCreateUser500RetriesExhausted(c *check.C) { 142 n := 0 143 s.redirectToTestSSO(func(w http.ResponseWriter, r *http.Request) { 144 w.WriteHeader(500) 145 n++ 146 }) 147 148 _, err := s.store.UserInfo("popper@lse.ac.uk") 149 c.Assert(err, check.NotNil) 150 c.Assert(err, check.ErrorMatches, `cannot look up user.*?got unexpected HTTP status code 500.*`) 151 c.Assert(n, check.Equals, 6) 152 }