diff --git a/src/backend/app-core/auth.go b/src/backend/app-core/auth.go index 6c81169f9a..c7650e2068 100644 --- a/src/backend/app-core/auth.go +++ b/src/backend/app-core/auth.go @@ -150,9 +150,11 @@ func (p *portalProxy) loginToUAA(c echo.Context) error { } // Connect to the given Endpoint +// Note, an admin user can connect an endpoint as a system endpoint to share it with others func (p *portalProxy) loginToCNSI(c echo.Context) error { log.Debug("loginToCNSI") cnsiGuid := c.FormValue("cnsi_guid") + var systemSharedToken = false if len(cnsiGuid) == 0 { return interfaces.NewHTTPShadowError( @@ -161,7 +163,12 @@ func (p *portalProxy) loginToCNSI(c echo.Context) error { "Need Endpoint GUID passed as form param") } - resp, err := p.DoLoginToCNSI(c, cnsiGuid) + systemSharedValue := c.FormValue("system_shared") + if len(systemSharedValue) > 0 { + systemSharedToken = systemSharedValue == "true" + } + + resp, err := p.DoLoginToCNSI(c, cnsiGuid, systemSharedToken) if err != nil { return err } @@ -176,7 +183,7 @@ func (p *portalProxy) loginToCNSI(c echo.Context) error { return nil } -func (p *portalProxy) DoLoginToCNSI(c echo.Context, cnsiGUID string) (*interfaces.LoginRes, error) { +func (p *portalProxy) DoLoginToCNSI(c echo.Context, cnsiGUID string, systemSharedToken bool) (*interfaces.LoginRes, error) { cnsiRecord, err := p.GetCNSIRecord(cnsiGUID) if err != nil { @@ -192,6 +199,23 @@ func (p *portalProxy) DoLoginToCNSI(c echo.Context, cnsiGUID string) (*interface return nil, echo.NewHTTPError(http.StatusUnauthorized, "Could not find correct session value") } + // Register as a system endpoint? + if systemSharedToken { + // User needs to be an admin + user, err := p.GetUAAUser(userID) + if err != nil { + return nil, echo.NewHTTPError(http.StatusUnauthorized, "Can not connect System Shared endpoint - could not check user") + } + + if !user.Admin { + return nil, echo.NewHTTPError(http.StatusUnauthorized, "Can not connect System Shared endpoint - user is not an administrator") + } + + // We are all good to go - change the userID, so we record this token against the system-shared user and not this specific user + // This is how we identify system-shared endpoint tokens + userID = tokens.SystemSharedUserGuid + } + // Ask the endpoint type to connect for _, plugin := range p.Plugins { endpointPlugin, err := plugin.GetEndpointPlugin() @@ -227,6 +251,9 @@ func (p *portalProxy) DoLoginToCNSI(c echo.Context, cnsiGUID string) (*interface cnsiUser, ok := p.GetCNSIUserFromToken(cnsiGUID, tokenRecord) if ok { + // If this is a system shared endpoint, then remove some metadata that should be send back to other users + santizeInfoForSystemSharedTokenUser(cnsiUser, systemSharedToken) + resp.User = cnsiUser } @@ -240,6 +267,14 @@ func (p *portalProxy) DoLoginToCNSI(c echo.Context, cnsiGUID string) (*interface "Endpoint connection not supported") } +func santizeInfoForSystemSharedTokenUser(cnsiUser *interfaces.ConnectedUser, isSysystemShared bool) { + if isSysystemShared { + cnsiUser.GUID = tokens.SystemSharedUserGuid + cnsiUser.Scopes = make([]string, 0) + cnsiUser.Name = "system_shared" + } +} + func (p *portalProxy) ConnectOAuth2(c echo.Context, cnsiRecord interfaces.CNSIRecord) (*interfaces.TokenRecord, error) { uaaRes, u, _, err := p.FetchOAuth2Token(cnsiRecord, c) if err != nil { @@ -316,6 +351,21 @@ func (p *portalProxy) logoutOfCNSI(c echo.Context) error { return fmt.Errorf("Unable to load CNSI record: %s", err) } + // Get the existing token to see if it is connected as a system shared endpoint + tr, ok := p.GetCNSITokenRecord(cnsiGUID, userGUID) + if ok && tr.SystemShared { + // User needs to be an admin + user, err := p.GetUAAUser(userGUID) + if err != nil { + return echo.NewHTTPError(http.StatusUnauthorized, "Can not disconnect System Shared endpoint - could not check user") + } + + if !user.Admin { + return echo.NewHTTPError(http.StatusUnauthorized, "Can not disconnect System Shared endpoint - user is not an administrator") + } + userGUID = tokens.SystemSharedUserGuid + } + // If cnsi is cf AND cf is auto-register only clear the entry if cnsiRecord.CNSIType == "cf" && p.GetConfig().AutoRegisterCFUrl == cnsiRecord.APIEndpoint.String() { log.Debug("Setting token record as disconnected") @@ -716,7 +766,7 @@ func (p *portalProxy) handleSessionExpiryHeader(c echo.Context) error { return nil } -func (p *portalProxy) getUAAUser(userGUID string) (*interfaces.ConnectedUser, error) { +func (p *portalProxy) GetUAAUser(userGUID string) (*interfaces.ConnectedUser, error) { log.Debug("getUAAUser") // get the uaa token record @@ -766,6 +816,10 @@ func (p *portalProxy) GetCNSIUserAndToken(cnsiGUID string, userGUID string) (*in } cnsiUser, ok := p.GetCNSIUserFromToken(cnsiGUID, &cfTokenRecord) + + // If this is a system shared endpoint, then remove some metadata that should be send back to other users + santizeInfoForSystemSharedTokenUser(cnsiUser, cfTokenRecord.SystemShared) + return cnsiUser, &cfTokenRecord, ok } diff --git a/src/backend/app-core/info.go b/src/backend/app-core/info.go index 9bb63fe84f..813bdfc768 100644 --- a/src/backend/app-core/info.go +++ b/src/backend/app-core/info.go @@ -40,7 +40,7 @@ func (p *portalProxy) getInfo(c echo.Context) (*interfaces.Info, error) { return nil, errors.New("Could not find session user_id") } - uaaUser, err := p.getUAAUser(userGUID) + uaaUser, err := p.GetUAAUser(userGUID) if err != nil { return nil, errors.New("Could not load session user data") } @@ -68,14 +68,16 @@ func (p *portalProxy) getInfo(c echo.Context) (*interfaces.Info, error) { for _, cnsi := range cnsiList { // Extend the CNSI record endpoint := &interfaces.EndpointDetail{ - CNSIRecord: cnsi, - Metadata: make(map[string]string), + CNSIRecord: cnsi, + Metadata: make(map[string]string), + SystemSharedToken: false, } // try to get the user info for this cnsi for the user cnsiUser, token, ok := p.GetCNSIUserAndToken(cnsi.GUID, userGUID) if ok { endpoint.User = cnsiUser endpoint.TokenMetadata = token.Metadata + endpoint.SystemSharedToken = token.SystemShared } cnsiType := cnsi.CNSIType s.Endpoints[cnsiType][cnsi.GUID] = endpoint diff --git a/src/backend/app-core/middleware.go b/src/backend/app-core/middleware.go index d09000a18d..a45d1669e4 100644 --- a/src/backend/app-core/middleware.go +++ b/src/backend/app-core/middleware.go @@ -116,7 +116,7 @@ func (p *portalProxy) adminMiddleware(h echo.HandlerFunc) echo.HandlerFunc { if err == nil { // check their admin status in UAA - u, err := p.getUAAUser(userID.(string)) + u, err := p.GetUAAUser(userID.(string)) if err != nil { return c.NoContent(http.StatusUnauthorized) } diff --git a/src/backend/app-core/mock_server_test.go b/src/backend/app-core/mock_server_test.go index a1bd57b1b2..87fd5b57c7 100644 --- a/src/backend/app-core/mock_server_test.go +++ b/src/backend/app-core/mock_server_test.go @@ -18,6 +18,7 @@ import ( "github.com/SUSE/stratos-ui/repository/crypto" "github.com/SUSE/stratos-ui/repository/interfaces" + "github.com/SUSE/stratos-ui/repository/tokens" "github.com/SUSE/stratos-ui/plugins/cloudfoundry" ) @@ -63,6 +64,7 @@ const mockCNSIGUID = "some-guid-1234" const mockCFGUID = "some-cf-guid-1234" const mockCEGUID = "some-hce-guid-1234" const mockUserGUID = "asd-gjfg-bob" +const mockAdminGUID = tokens.SystemSharedUserGuid const mockURLString = "http://localhost:9999/some/fake/url/" @@ -168,15 +170,15 @@ func expectCFAndCERows() sqlmock.Rows { } func expectTokenRow() sqlmock.Rows { - return sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "OAuth2", "") + return sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "OAuth2", "", mockUserGUID) } func expectEncryptedTokenRow(mockEncryptionKey []byte) sqlmock.Rows { encryptedUaaToken, _ := crypto.EncryptToken(mockEncryptionKey, mockUAAToken) - return sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(encryptedUaaToken, encryptedUaaToken, mockTokenExpiry, false, "OAuth2", "") + return sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(encryptedUaaToken, encryptedUaaToken, mockTokenExpiry, false, "OAuth2", "", mockUserGUID) } func setupHTTPTest(req *http.Request) (*httptest.ResponseRecorder, *echo.Echo, echo.Context, *portalProxy, *sql.DB, sqlmock.Sqlmock) { diff --git a/src/backend/app-core/oauth_requests_test.go b/src/backend/app-core/oauth_requests_test.go index e3637bf262..2a3981068e 100644 --- a/src/backend/app-core/oauth_requests_test.go +++ b/src/backend/app-core/oauth_requests_test.go @@ -97,10 +97,10 @@ func TestDoOauthFlowRequestWithValidToken(t *testing.T) { // p.getCNSIRequestRecords(cnsiRequest) -> // p.getCNSITokenRecord(r.GUID, r.UserGUID) -> // tokenRepo.FindCNSIToken(cnsiGUID, userGUID) - expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(encryptedToken, encryptedToken, tokenExpiration, false, "OAuth2", "") + expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(encryptedToken, encryptedToken, tokenExpiration, false, "OAuth2", "", mockUserGUID) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRow) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) @@ -227,10 +227,10 @@ func TestDoOauthFlowRequestWithExpiredToken(t *testing.T) { // p.getCNSIRequestRecords(cnsiRequest) -> // p.getCNSITokenRecord(r.GUID, r.UserGUID) -> // tokenRepo.FindCNSIToken(cnsiGUID, userGUID) - expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "") + expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "", mockUserGUID) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRow) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) @@ -240,10 +240,10 @@ func TestDoOauthFlowRequestWithExpiredToken(t *testing.T) { WithArgs(mockCNSIGUID). WillReturnRows(expectedCNSIRecordRow) - expectedCNSITokenRecordRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "") + expectedCNSITokenRecordRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "", mockUserGUID) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRecordRow) mock.ExpectQuery(selectAnyFromTokens). @@ -370,10 +370,10 @@ func TestDoOauthFlowRequestWithFailedRefreshMethod(t *testing.T) { // p.getCNSIRequestRecords(cnsiRequest) -> // p.getCNSITokenRecord(r.GUID, r.UserGUID) -> // tokenRepo.FindCNSIToken(cnsiGUID, userGUID) - expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "") + expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(encryptedUAAToken, encryptedUAAToken, tokenExpiration, false, "OAuth2", "", mockUserGUID) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRow) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) @@ -617,7 +617,7 @@ func TestRefreshTokenWithDatabaseErrorOnSave(t *testing.T) { expectedCNSITokenRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). AddRow(mockUAAToken, mockUAAToken, tokenExpiration, false, "OAuth2", "") mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRow) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) @@ -630,11 +630,11 @@ func TestRefreshTokenWithDatabaseErrorOnSave(t *testing.T) { expectedCNSITokenRecordRow := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). AddRow(mockUAAToken, mockUAAToken, tokenExpiration, false, "OAuth2", "") mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectedCNSITokenRecordRow) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCNSIGUID, mockUserGUID). + WithArgs(mockCNSIGUID, mockUserGUID, mockAdminGUID). WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow("1")) // p.saveCNSIToken(cnsiGUID, *u, uaaRes.AccessToken, uaaRes.RefreshToken) diff --git a/src/backend/app-core/passthrough_test.go b/src/backend/app-core/passthrough_test.go index 9ced176049..bc2fda8337 100644 --- a/src/backend/app-core/passthrough_test.go +++ b/src/backend/app-core/passthrough_test.go @@ -72,7 +72,7 @@ func TestPassthroughDoRequest(t *testing.T) { // p.getCNSITokenRecord(r.GUID, r.UserGUID) -> // tokenRepo.FindCNSIToken(cnsiGUID, userGUID) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCFGUID, mockUserGUID). + WithArgs(mockCFGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectEncryptedTokenRow(pp.Config.EncryptionKeyInBytes)) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) @@ -81,7 +81,7 @@ func TestPassthroughDoRequest(t *testing.T) { WillReturnRows(expectCFRow()) mock.ExpectQuery(selectAnyFromTokens). - WithArgs(mockCFGUID, mockUserGUID). + WithArgs(mockCFGUID, mockUserGUID, mockAdminGUID). WillReturnRows(expectEncryptedTokenRow(pp.Config.EncryptionKeyInBytes)) // p.GetCNSIRecord(r.GUID) -> cnsiRepo.Find(guid) diff --git a/src/backend/app-core/repository/interfaces/portal_proxy.go b/src/backend/app-core/repository/interfaces/portal_proxy.go index d95505bb0d..610a0187aa 100644 --- a/src/backend/app-core/repository/interfaces/portal_proxy.go +++ b/src/backend/app-core/repository/interfaces/portal_proxy.go @@ -30,7 +30,7 @@ type PortalProxy interface { SaveConsoleConfig(consoleConfig *ConsoleConfig, consoleRepoInterface interface{}) error RefreshOAuthToken(skipSSLValidation bool, cnsiGUID, userGUID, client, clientSecret, tokenEndpoint string) (t TokenRecord, err error) - DoLoginToCNSI(c echo.Context, cnsiGUID string) (*LoginRes, error) + DoLoginToCNSI(c echo.Context, cnsiGUID string, systemSharedToken bool) (*LoginRes, error) // Expose internal portal proxy records to extensions GetCNSIRecord(guid string) (CNSIRecord, error) GetCNSIRecordByEndpoint(endpoint string) (CNSIRecord, error) @@ -49,6 +49,7 @@ type PortalProxy interface { GetUsername(userid string) (string, error) RefreshUAALogin(username, password string, store bool) error GetUserTokenInfo(tok string) (u *JWTUserTokenInfo, err error) + GetUAAUser(userGUID string) (*ConnectedUser, error) // Proxy API requests ProxyRequest(c echo.Context, uri *url.URL) (map[string]*CNSIRequest, error) diff --git a/src/backend/app-core/repository/interfaces/structs.go b/src/backend/app-core/repository/interfaces/structs.go index 66d1c0964a..34f0dfe547 100644 --- a/src/backend/app-core/repository/interfaces/structs.go +++ b/src/backend/app-core/repository/interfaces/structs.go @@ -71,6 +71,7 @@ type TokenRecord struct { Disconnected bool AuthType string Metadata string + SystemShared bool } type CFInfo struct { @@ -144,9 +145,10 @@ type Info struct { // Extends CNSI Record and adds the user type EndpointDetail struct { *CNSIRecord - User *ConnectedUser `json:"user"` - Metadata map[string]string `json:"metadata,omitempty"` - TokenMetadata string `json:"-"` + User *ConnectedUser `json:"user"` + Metadata map[string]string `json:"metadata,omitempty"` + TokenMetadata string `json:"-"` + SystemSharedToken bool `json:"system_shared_token"` } // Versions - response returned to caller from a getVersions action diff --git a/src/backend/app-core/repository/tokens/pgsql_tokens.go b/src/backend/app-core/repository/tokens/pgsql_tokens.go index be78a375fe..0f073240b2 100644 --- a/src/backend/app-core/repository/tokens/pgsql_tokens.go +++ b/src/backend/app-core/repository/tokens/pgsql_tokens.go @@ -26,13 +26,13 @@ var updateAuthToken = `UPDATE tokens SET auth_token = $1, refresh_token = $2, token_expiry = $3 WHERE user_guid = $4 AND token_type = $5` -var findCNSIToken = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data +var findCNSIToken = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data, user_guid FROM tokens - WHERE cnsi_guid = $1 AND user_guid = $2 AND token_type = 'cnsi'` + WHERE cnsi_guid = $1 AND (user_guid = $2 OR user_guid = $3) AND token_type = 'cnsi'` -var findCNSITokenConnected = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data +var findCNSITokenConnected = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data, user_guid FROM tokens - WHERE cnsi_guid = $1 AND user_guid = $2 AND token_type = 'cnsi' AND disconnected = '0'` + WHERE cnsi_guid = $1 AND (user_guid = $2 OR user_guid = $3) AND token_type = 'cnsi' AND disconnected = '0'` var countCNSITokens = `SELECT COUNT(*) FROM tokens @@ -304,13 +304,14 @@ func (p *PgsqlTokenRepository) findCNSIToken(cnsiGUID string, userGUID string, e disconnected bool authType string metadata string + tokenUserGUID string ) var err error if includeDisconnected { - err = p.db.QueryRow(findCNSIToken, cnsiGUID, userGUID).Scan(&ciphertextAuthToken, &ciphertextRefreshToken, &tokenExpiry, &disconnected, &authType, &metadata) + err = p.db.QueryRow(findCNSIToken, cnsiGUID, userGUID, SystemSharedUserGuid).Scan(&ciphertextAuthToken, &ciphertextRefreshToken, &tokenExpiry, &disconnected, &authType, &metadata, &tokenUserGUID) } else { - err = p.db.QueryRow(findCNSITokenConnected, cnsiGUID, userGUID).Scan(&ciphertextAuthToken, &ciphertextRefreshToken, &tokenExpiry, &disconnected, &authType, &metadata) + err = p.db.QueryRow(findCNSITokenConnected, cnsiGUID, userGUID, SystemSharedUserGuid).Scan(&ciphertextAuthToken, &ciphertextRefreshToken, &tokenExpiry, &disconnected, &authType, &metadata, &tokenUserGUID) } if err != nil { @@ -339,6 +340,7 @@ func (p *PgsqlTokenRepository) findCNSIToken(cnsiGUID string, userGUID string, e tr.Disconnected = disconnected tr.AuthType = authType tr.Metadata = metadata + tr.SystemShared = tokenUserGUID == SystemSharedUserGuid return *tr, nil } diff --git a/src/backend/app-core/repository/tokens/pgsql_tokens_test.go b/src/backend/app-core/repository/tokens/pgsql_tokens_test.go index 8fb6719d34..5d8ba10a47 100644 --- a/src/backend/app-core/repository/tokens/pgsql_tokens_test.go +++ b/src/backend/app-core/repository/tokens/pgsql_tokens_test.go @@ -20,7 +20,7 @@ const ( countTokensSql = `SELECT COUNT` insertTokenSql = `INSERT INTO tokens` updateUAATokenSql = `UPDATE tokens` - findTokenSql = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data FROM tokens .*` + findTokenSql = `SELECT auth_token, refresh_token, token_expiry, disconnected, auth_type, meta_data, user_guid FROM tokens .*` findUAATokenSql = `SELECT auth_token, refresh_token, token_expiry FROM tokens WHERE token_type = 'uaa' AND .*` deleteFromTokensSql = `DELETE FROM tokens` ) @@ -343,8 +343,8 @@ func TestFindCNSITokens(t *testing.T) { }) Convey("should fail to decrypt with invalid encryptionKey", func() { - rs := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "oauth", "") + rs := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "oauth", "", mockUserGuid) mock.ExpectQuery(findTokenSql). WillReturnRows(rs) @@ -355,8 +355,8 @@ func TestFindCNSITokens(t *testing.T) { }) Convey("Success case", func() { - rs := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data"}). - AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "oauth", "") + rs := sqlmock.NewRows([]string{"auth_token", "refresh_token", "token_expiry", "disconnected", "auth_type", "meta_data", "user_guid"}). + AddRow(mockUAAToken, mockUAAToken, mockTokenExpiry, false, "oauth", "", mockUserGuid) mock.ExpectQuery(findTokenSql). WillReturnRows(rs) diff --git a/src/backend/app-core/repository/tokens/tokens.go b/src/backend/app-core/repository/tokens/tokens.go index e9781c83fd..0d97161d29 100644 --- a/src/backend/app-core/repository/tokens/tokens.go +++ b/src/backend/app-core/repository/tokens/tokens.go @@ -9,6 +9,8 @@ type Token struct { Record interfaces.TokenRecord } +const SystemSharedUserGuid = "00000000-1111-2222-3333-444444444444" // User ID for the system shared user for endpoints + // Repository is an application of the repository pattern for storing tokens type Repository interface { FindAuthToken(userGUID string, encryptionKey []byte) (interfaces.TokenRecord, error) diff --git a/src/backend/cloudfoundry/main.go b/src/backend/cloudfoundry/main.go index 4c9eae7085..338f246710 100644 --- a/src/backend/cloudfoundry/main.go +++ b/src/backend/cloudfoundry/main.go @@ -133,7 +133,7 @@ func (c *CloudFoundrySpecification) cfLoginHook(context echo.Context) error { log.Infof("No, user should not auto-connect to auto-registered cloud foundry %s (previsouly disoconnected). ", cfAPI) } else { log.Infof("Yes, user should auto-connect to auto-registered cloud foundry %s.", cfAPI) - _, err := c.portalProxy.DoLoginToCNSI(context, cfCnsi.GUID) + _, err := c.portalProxy.DoLoginToCNSI(context, cfCnsi.GUID, false) return err } diff --git a/src/frontend/app/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.html b/src/frontend/app/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.html index cf090e00f0..53e4802fd5 100644 --- a/src/frontend/app/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.html +++ b/src/frontend/app/features/endpoints/connect-endpoint-dialog/connect-endpoint-dialog.component.html @@ -22,6 +22,7 @@