1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the LGPLv3, see LICENCE file for details.
15
"github.com/juju/testing"
16
jc "github.com/juju/testing/checkers"
17
"github.com/juju/usso"
18
gc "gopkg.in/check.v1"
19
"gopkg.in/juju/environschema.v1/form"
20
"gopkg.in/macaroon-bakery.v1/httpbakery"
22
"github.com/juju/idmclient/params"
23
"github.com/juju/idmclient/ussologin"
26
type visitWebPageSuite struct {
28
server *httptest.Server
31
var _ = gc.Suite(&visitWebPageSuite{})
33
func (s *visitWebPageSuite) SetUpTest(c *gc.C) {
34
s.server = httptest.NewServer(&loginMethodsHandler{"http://example.com"})
37
func (s *visitWebPageSuite) TearDownTest(c *gc.C) {
41
func (s *visitWebPageSuite) TestCorrectUserPasswordSentToUSSOServer(c *gc.C) {
42
ussoStub := &ussoServerStub{}
43
s.PatchValue(ussologin.Server, ussoStub)
44
filler := &testFiller{
45
map[string]interface{}{
46
ussologin.UserKey: "foobar",
47
ussologin.PassKey: "pass",
48
ussologin.OTPKey: "1234",
50
store := &testTokenStore{}
51
f := ussologin.VisitWebPage("testToken", &http.Client{}, filler, store)
52
u, err := url.Parse(s.server.URL)
53
c.Assert(err, jc.ErrorIsNil)
55
c.Assert(err, jc.ErrorIsNil)
56
ussoStub.CheckCall(c, 0, "GetTokenWithOTP", "foobar", "pass", "1234", "testToken")
57
store.CheckCallNames(c, "Get", "Put")
60
func (s *visitWebPageSuite) TestLoginFailsToGetToken(c *gc.C) {
61
ussoStub := &ussoServerStub{}
62
ussoStub.SetErrors(errors.New("something failed"))
63
s.PatchValue(ussologin.Server, ussoStub)
64
filler := &testFiller{
65
map[string]interface{}{
66
ussologin.UserKey: "foobar",
67
ussologin.PassKey: "pass",
68
ussologin.OTPKey: "1234",
70
f := ussologin.VisitWebPage("testToken", &http.Client{}, filler, &testTokenStore{})
71
u, err := url.Parse(s.server.URL)
72
c.Assert(err, jc.ErrorIsNil)
74
c.Assert(err, gc.ErrorMatches, "cannot get token: something failed")
77
func (s *visitWebPageSuite) TestLoginWithExistingToken(c *gc.C) {
78
ussoStub := &ussoServerStub{}
79
s.PatchValue(ussologin.Server, ussoStub)
80
f := ussologin.VisitWebPage("testToken", &http.Client{}, &testFiller{}, &testTokenStore{tok: &usso.SSOData{}})
81
u, err := url.Parse(s.server.URL)
82
c.Assert(err, jc.ErrorIsNil)
84
c.Assert(err, jc.ErrorIsNil)
85
ussoStub.CheckNoCalls(c) //If we have a token we shouldn't call the ussoServer
88
func (s *visitWebPageSuite) TestLoginWithExistingMalformedToken(c *gc.C) {
89
ussoStub := &ussoServerStub{}
90
s.PatchValue(ussologin.Server, ussoStub)
91
filler := &testFiller{
92
map[string]interface{}{
93
ussologin.UserKey: "foobar",
94
ussologin.PassKey: "pass",
95
ussologin.OTPKey: "1234",
97
tokenPath := fmt.Sprintf("%s/token", c.MkDir())
98
err := ioutil.WriteFile(tokenPath, []byte("foobar"), 0600) // Write a malformed token
99
c.Assert(err, jc.ErrorIsNil)
100
f := ussologin.VisitWebPage("testToken", &http.Client{}, filler, ussologin.NewFileTokenStore(tokenPath))
101
u, err := url.Parse(s.server.URL)
102
c.Assert(err, jc.ErrorIsNil)
104
c.Assert(err, jc.ErrorIsNil)
105
ussoStub.CheckCall(c, 0, "GetTokenWithOTP", "foobar", "pass", "1234", "testToken")
108
func (s *visitWebPageSuite) TestVisitWebPageWorksIfNilStoreGiven(c *gc.C) {
109
ussoStub := &ussoServerStub{}
110
s.PatchValue(ussologin.Server, ussoStub)
111
filler := &testFiller{
112
map[string]interface{}{
113
ussologin.UserKey: "foobar",
114
ussologin.PassKey: "pass",
115
ussologin.OTPKey: "1234",
117
f := ussologin.VisitWebPage("testToken", &http.Client{}, filler, nil)
118
u, err := url.Parse(s.server.URL)
119
c.Assert(err, jc.ErrorIsNil)
121
c.Assert(err, jc.ErrorIsNil)
122
ussoStub.CheckCall(c, 0, "GetTokenWithOTP", "foobar", "pass", "1234", "testToken")
125
func (s *visitWebPageSuite) TestFailedToReadLoginParameters(c *gc.C) {
126
ussoStub := &ussoServerStub{}
127
s.PatchValue(ussologin.Server, ussoStub)
128
filler := &errFiller{}
129
f := ussologin.VisitWebPage("testToken", &http.Client{}, filler, &testTokenStore{})
130
u, err := url.Parse(s.server.URL)
131
c.Assert(err, jc.ErrorIsNil)
133
c.Assert(err, gc.ErrorMatches, "cannot read login parameters: something failed")
134
ussoStub.CheckNoCalls(c)
137
type testFiller struct {
138
form map[string]interface{}
141
func (t *testFiller) Fill(f form.Form) (map[string]interface{}, error) {
145
type errFiller struct{}
147
func (t *errFiller) Fill(f form.Form) (map[string]interface{}, error) {
148
return nil, errors.New("something failed")
151
type ussoServerStub struct {
155
func (u *ussoServerStub) GetTokenWithOTP(email, password, otp, tokenName string) (*usso.SSOData, error) {
156
u.AddCall("GetTokenWithOTP", email, password, otp, tokenName)
157
return &usso.SSOData{}, u.NextErr()
160
type loginMethodsHandler struct {
164
func (l *loginMethodsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
165
w.Header().Set("Content-Type", "application/json")
166
lm := params.LoginMethods{
167
UbuntuSSOOAuth: l.responseURL,
169
writer := json.NewEncoder(w)
170
err := writer.Encode(&lm)
176
var _ httpbakery.Visitor = &ussologin.Visitor{}