diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go index 5089914c..e7ee4386 100644 --- a/connector/mock/connectortest.go +++ b/connector/mock/connectortest.go @@ -107,6 +107,7 @@ func (p passwordConnector) Login(ctx context.Context, s connector.Scopes, userna Username: "Kilgore Trout", Email: "kilgore@kilgore.trout", EmailVerified: true, + ConnectorData: []byte(`{"test": "true"}`), }, true, nil } return identity, false, nil diff --git a/server/handlers.go b/server/handlers.go index 4144dd1f..d25cac52 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -1194,9 +1194,10 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli return } offlineSessions := storage.OfflineSessions{ - UserID: refresh.Claims.UserID, - ConnID: refresh.ConnectorID, - Refresh: make(map[string]*storage.RefreshTokenRef), + UserID: refresh.Claims.UserID, + ConnID: refresh.ConnectorID, + Refresh: make(map[string]*storage.RefreshTokenRef), + ConnectorData: identity.ConnectorData, } offlineSessions.Refresh[tokenRef.ClientID] = &tokenRef @@ -1226,6 +1227,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli // Update existing OfflineSession obj with new RefreshTokenRef. if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { old.Refresh[tokenRef.ClientID] = &tokenRef + old.ConnectorData = identity.ConnectorData return old, nil }); err != nil { s.logger.Errorf("failed to update offline session: %v", err) diff --git a/server/handlers_test.go b/server/handlers_test.go index a808e5a1..61b3ece6 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -7,6 +7,8 @@ import ( "errors" "net/http" "net/http/httptest" + "net/url" + "path" "testing" "time" @@ -227,3 +229,75 @@ func TestHandleAuthCode(t *testing.T) { }) } } + +func mockConnectorDataTestStorage(t *testing.T, s storage.Storage) { + c := storage.Client{ + ID: "test", + Secret: "barfoo", + RedirectURIs: []string{"foo://bar.com/", "https://auth.example.com"}, + Name: "dex client", + LogoURL: "https://goo.gl/JIyzIC", + } + + err := s.CreateClient(c) + require.NoError(t, err) + + c1 := storage.Connector{ + ID: "test", + Type: "mockPassword", + Name: "mockPassword", + Config: []byte(`{ +"username": "test", +"password": "test" +}`), + } + + err = s.CreateConnector(c1) + require.NoError(t, err) +} + +func TestPasswordConnectorDataNotEmpty(t *testing.T) { + t0 := time.Now() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Setup a dex server. + httpServer, s := newTestServer(ctx, t, func(c *Config) { + c.PasswordConnector = "test" + c.Now = func() time.Time { return t0 } + }) + defer httpServer.Close() + + mockConnectorDataTestStorage(t, s.storage) + + u, err := url.Parse(s.issuerURL.String()) + require.NoError(t, err) + + u.Path = path.Join(u.Path, "/token") + v := url.Values{} + v.Add("scope", "openid offline_access email") + v.Add("grant_type", "password") + v.Add("username", "test") + v.Add("password", "test") + + req, _ := http.NewRequest("POST", u.String(), bytes.NewBufferString(v.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") + req.SetBasicAuth("test", "barfoo") + + rr := httptest.NewRecorder() + s.ServeHTTP(rr, req) + + require.Equal(t, 200, rr.Code) + + // Check that we received expected refresh token + var ref struct { + Token string `json:"refresh_token"` + } + err = json.Unmarshal(rr.Body.Bytes(), &ref) + require.NoError(t, err) + + newSess, err := s.storage.GetOfflineSessions("0-385-28089-0", "test") + require.NoError(t, err) + require.Equal(t, `{"test": "true"}`, string(newSess.ConnectorData)) +}