Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
Make WIT URL configurable via env var (#116)
Browse files Browse the repository at this point in the history
lets let folks define the wit URL completely
if not specified we default to using `api.$domain`
  • Loading branch information
alexeykazakov authored Sep 22, 2017
1 parent 011d2e1 commit b184feb
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 59 deletions.
5 changes: 3 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ serviceaccount.privatekeyid: 9MLnViaRkhVj1GT9kpWUkwHIwUD-wZfUxR-3CpkE-Xs
#notapproved.redirect : https://manage.openshift.com/openshiftio

# ----------------------------
# Keycloak OAuth2.0 configuration
# Keycloak configuration
# ----------------------------

keycloak.client.id : fabric8-online-platform
Expand All @@ -105,4 +105,5 @@ keycloak.testuser.secret : testuser
keycloak.testuser2.name : testuser2
keycloak.testuser2.secret : testuser2

keycloak.url : https://sso.prod-preview.openshift.io
#keycloak.url : https://sso.prod-preview.openshift.io
#wit.url : https://api.prod-preview.openshift.io
22 changes: 13 additions & 9 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"strings"
"time"

log "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"

"github.com/fabric8-services/fabric8-auth/rest"

log "github.com/Sirupsen/logrus"
"github.com/goadesign/goa"
"github.com/pkg/errors"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)

// String returns the current configuration as a string
Expand Down Expand Up @@ -55,7 +55,6 @@ const (
varKeycloakTesUser2Name = "keycloak.testuser2.name"
varKeycloakTesUser2Secret = "keycloak.testuser2.secret"
varKeycloakURL = "keycloak.url"
varKeycloakEndpoingCerts = "keycloak.endpoing.certs"
varKeycloakEndpointAdmin = "keycloak.endpoint.admin"
varKeycloakEndpointAuth = "keycloak.endpoint.auth"
varKeycloakEndpointToken = "keycloak.endpoint.token"
Expand All @@ -81,6 +80,7 @@ const (
varLogLevel = "log.level"
varLogJSON = "log.json"
varWITDomainPrefix = "wit.domain.prefix"
varWITURL = "wit.url"
)

// ConfigurationData encapsulates the Viper configuration object which stores the configuration data in-memory.
Expand Down Expand Up @@ -477,12 +477,16 @@ func (c *ConfigurationData) GetWITDomainPrefix() string {
return c.v.GetString(varWITDomainPrefix)
}

// GetWITEndpoint returns the API endpoint where WIT is running.
func (c *ConfigurationData) GetWITEndpoint(req *goa.RequestData) (string, error) {
// GetWITURL returns the WIT URL where WIT is running
// If AUTH_WIT_URL is not set and Auth in not in Dev Mode then we calculate the URL from the domain
func (c *ConfigurationData) GetWITURL(req *goa.RequestData) (string, error) {
if c.v.IsSet(varWITURL) {
return c.v.GetString(varWITURL), nil
}
if c.IsPostgresDeveloperModeEnabled() {
return devModeWITURL, nil
}
return c.getWITURL(req)
return c.calculateWITURL(req)
}

func (c *ConfigurationData) getKeycloakOpenIDConnectEndpoint(req *goa.RequestData, endpointVarName string, pathSufix string) (string, error) {
Expand Down Expand Up @@ -539,7 +543,7 @@ func (c *ConfigurationData) getKeycloakURL(req *goa.RequestData, path string) (s
return newURL, nil
}

func (c *ConfigurationData) getWITURL(req *goa.RequestData) (string, error) {
func (c *ConfigurationData) calculateWITURL(req *goa.RequestData) (string, error) {
scheme := "http"
if req.URL != nil && req.URL.Scheme == "https" { // isHTTPS
scheme = "https"
Expand Down
46 changes: 33 additions & 13 deletions configuration/configuration_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"time"

jwt "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go"
"github.com/fabric8-services/fabric8-auth/configuration"
"github.com/fabric8-services/fabric8-auth/resource"
"github.com/goadesign/goa"
Expand Down Expand Up @@ -203,45 +203,65 @@ func TestGetKeycloakUserInfoEndpointOKrSetByEnvVaribaleOK(t *testing.T) {
checkGetKeycloakEndpointSetByEnvVaribaleOK(t, "AUTH_KEYCLOAK_ENDPOINT_ACCOUNT", config.GetKeycloakAccountEndpoint)
}

func TestGetWITEndpointNotDevModeOK(t *testing.T) {
func TestGetWITURLNotDevModeOK(t *testing.T) {
resource.Require(t, resource.UnitTest)
existingWITURL := os.Getenv("AUTH_WIT_DOMAIN_PREFIX")
existingWITprefix := os.Getenv("AUTH_WIT_DOMAIN_PREFIX")
existingDevMode := os.Getenv("AUTH_DEVELOPER_MODE_ENABLED")
defer func() {
resetConfiguration(defaultValuesConfigFilePath)
os.Setenv("AUTH_WIT_DOMAIN_PREFIX", existingWITURL)
os.Setenv("AUTH_WIT_DOMAIN_PREFIX", existingWITprefix)
os.Setenv("AUTH_DEVELOPER_MODE_ENABLED", existingDevMode)
}()

os.Setenv("AUTH_DEVELOPER_MODE_ENABLED", "false")

// Ensure that what we set as env variable is actually what we get
computedWITEndpoint, err := config.GetWITEndpoint(reqShort)
computedWITURL, err := config.GetWITURL(reqShort)
assert.Nil(t, err)
assert.Equal(t, "http://api.domain.org", computedWITEndpoint)
assert.Equal(t, "http://api.domain.org", computedWITURL)

os.Setenv("AUTH_WIT_DOMAIN_PREFIX", "myauthsubdomain")
computedWITEndpoint, err = config.GetWITEndpoint(reqLong)
computedWITURL, err = config.GetWITURL(reqLong)
assert.Nil(t, err)
assert.Equal(t, "http://myauthsubdomain.service.domain.org", computedWITEndpoint)
assert.Equal(t, "http://myauthsubdomain.service.domain.org", computedWITURL)
}

func TestGetWITEndpointDevModeOK(t *testing.T) {
func TestGetWITURLDevModeOK(t *testing.T) {
resource.Require(t, resource.UnitTest)
existingWITURL := os.Getenv("AUTH_WIT_DOMAIN_PREFIX")
existingWITprefix := os.Getenv("AUTH_WIT_DOMAIN_PREFIX")
existingDevMode := os.Getenv("AUTH_DEVELOPER_MODE_ENABLED")
defer func() {
resetConfiguration(defaultValuesConfigFilePath)
os.Setenv("AUTH_WIT_DOMAIN_PREFIX", existingWITURL)
os.Setenv("AUTH_WIT_DOMAIN_PREFIX", existingWITprefix)
os.Setenv("AUTH_DEVELOPER_MODE_ENABLED", existingDevMode)
}()

os.Setenv("AUTH_DEVELOPER_MODE_ENABLED", "true")

// Ensure that what we set as env variable is actually what we get
computedWITEndpoint, err := config.GetWITEndpoint(reqShort)
computedWITURL, err := config.GetWITURL(reqShort)
assert.Nil(t, err)
assert.Equal(t, "http://localhost:8080", computedWITEndpoint)
assert.Equal(t, "http://localhost:8080", computedWITURL)
}

func TestGetWITURLSetViaEnvVarOK(t *testing.T) {
resource.Require(t, resource.UnitTest)
existingWITURL := os.Getenv("AUTH_WIT_URL")
defer func() {
resetConfiguration(defaultValuesConfigFilePath)
if existingWITURL != "" {
os.Setenv("AUTH_WIT_URL", existingWITURL)
} else {
os.Unsetenv("AUTH_WIT_URL")
}
}()

os.Setenv("AUTH_WIT_URL", "https://new.wit.url")

// Ensure that what we set as env variable is actually what we get
computedWITURL, err := config.GetWITURL(reqShort)
assert.Nil(t, err)
assert.Equal(t, "https://new.wit.url", computedWITURL)
}

func checkGetKeycloakEndpointOK(t *testing.T, expectedEndpoint string, getEndpoint func(req *goa.RequestData) (string, error)) {
Expand Down
2 changes: 1 addition & 1 deletion controller/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type LoginConfiguration interface {
GetValidRedirectURLs(*goa.RequestData) (string, error)
GetHeaderMaxLength() int64
GetNotApprovedRedirect() string
GetWITEndpoint(*goa.RequestData) (string, error)
GetWITURL(*goa.RequestData) (string, error)
}

// LoginController implements the login resource.
Expand Down
6 changes: 3 additions & 3 deletions controller/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type UsersControllerConfiguration interface {
GetCacheControlUsers() string
GetCacheControlUser() string
GetKeycloakAccountEndpoint(*goa.RequestData) (string, error)
GetWITEndpoint(*goa.RequestData) (string, error)
GetWITURL(*goa.RequestData) (string, error)
}

// NewUsersController creates a users controller.
Expand Down Expand Up @@ -388,11 +388,11 @@ func (c *UsersController) updateWITUser(ctx *app.UpdateUsersContext, request *go
Type: ctx.Payload.Data.Type,
},
}
WITEndpoint, err := c.config.GetWITEndpoint(ctx.RequestData)
witURL, err := c.config.GetWITURL(ctx.RequestData)
if err != nil {
return err
}
return c.RemoteWITService.UpdateWITUser(ctx, request, updateUserPayload, WITEndpoint, identityID)
return c.RemoteWITService.UpdateWITUser(ctx, request, updateUserPayload, witURL, identityID)
}

func isEmailValid(email string) bool {
Expand Down
6 changes: 3 additions & 3 deletions controller/users_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,15 +951,15 @@ func (s *TestUsersSuite) generateUsersTag(allUsers app.UserArray) string {

type dummyRemoteWITService struct{}

func (r *dummyRemoteWITService) UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, WITEndpoint string, identityID string) error {
func (r *dummyRemoteWITService) UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, witURL string, identityID string) error {
return nil
}

func (r *dummyRemoteWITService) GetWITUser(ctx context.Context, req *goa.RequestData, WITEndpointUserProfile string, accessToken *string) (*account.User, *account.Identity, error) {
func (r *dummyRemoteWITService) GetWITUser(ctx context.Context, req *goa.RequestData, witURL string, accessToken *string) (*account.User, *account.Identity, error) {
return nil, nil, nil
}

func (r *dummyRemoteWITService) CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, WITEndpoint string, identityID string) error {
func (r *dummyRemoteWITService) CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, witURL string, identityID string) error {
return nil
}

Expand Down
28 changes: 14 additions & 14 deletions login/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type LoginServiceConfiguration interface {
GetKeycloakEndpointBroker(*goa.RequestData) (string, error)
GetValidRedirectURLs(*goa.RequestData) (string, error)
GetNotApprovedRedirect() string
GetWITEndpoint(*goa.RequestData) (string, error)
GetWITURL(*goa.RequestData) (string, error)
}

// NewKeycloakOAuthProvider creates a new login.Service capable of using keycloak for authorization
Expand Down Expand Up @@ -110,7 +110,7 @@ func (keycloak *KeycloakOAuthProvider) Perform(ctx *app.LoginLoginContext, confi
return jsonapi.JSONErrorResponse(ctx, autherrors.NewInternalError(ctx, err))
}

WITEndpointUserProfile, err := serviceConfig.GetWITEndpoint(ctx.RequestData)
witURL, err := serviceConfig.GetWITURL(ctx.RequestData)
if err != nil {
return jsonapi.JSONErrorResponse(ctx, autherrors.NewInternalError(ctx, err))
}
Expand Down Expand Up @@ -164,11 +164,11 @@ func (keycloak *KeycloakOAuthProvider) Perform(ctx *app.LoginLoginContext, confi
"known_referrer": knownReferrer,
}, "exchanged code to access token")

usr, identity, err := keycloak.remoteWITService.GetWITUser(ctx, ctx.RequestData, WITEndpointUserProfile, &keycloakToken.AccessToken)
usr, identity, err := keycloak.remoteWITService.GetWITUser(ctx, ctx.RequestData, witURL, &keycloakToken.AccessToken)
if err != nil {
log.Error(ctx, map[string]interface{}{
"err": err,
"wit_user_profile_endpoint": WITEndpointUserProfile,
"err": err,
"wit_url": witURL,
}, "unable to get user from WIT")
// Unable to connect to wit but it's not a fatal error. Proceed with login.
}
Expand Down Expand Up @@ -209,24 +209,24 @@ func (keycloak *KeycloakOAuthProvider) Perform(ctx *app.LoginLoginContext, confi

// new user for WIT
if newUser {
err = keycloak.remoteWITService.CreateWITUser(ctx, ctx.RequestData, usr, identity, WITEndpointUserProfile, identity.ID.String())
err = keycloak.remoteWITService.CreateWITUser(ctx, ctx.RequestData, usr, identity, witURL, identity.ID.String())
if err != nil {
log.Error(ctx, map[string]interface{}{
"err": err,
"identity_id": identity.ID,
"username": identity.Username,
"wit_user_profile_endpoint": WITEndpointUserProfile,
"err": err,
"identity_id": identity.ID,
"username": identity.Username,
"wit_url": witURL,
}, "unable to create user in WIT ")
// let's carry on instead of erroring out ?
}
} else {
err = keycloak.updateWITUser(ctx, ctx.RequestData, usr, identity, WITEndpointUserProfile, identity.ID.String())
err = keycloak.updateWITUser(ctx, ctx.RequestData, usr, identity, witURL, identity.ID.String())
if err != nil {
log.Error(ctx, map[string]interface{}{
"identity_id": identity.ID,
"username": identity.Username,
"err": err,
"wit_user_profile_endpoint": WITEndpointUserProfile,
"wit_url": witURL,
}, "unable to update user in WIT ")
// let's carry on instead of erroring out ?
}
Expand Down Expand Up @@ -845,7 +845,7 @@ func (keycloak *KeycloakOAuthProvider) CreateOrUpdateKeycloakUser(accessToken st
return user, identity, err
}

func (keycloak *KeycloakOAuthProvider) updateWITUser(ctx context.Context, request *goa.RequestData, user *account.User, identity *account.Identity, WITEndpointUserProfile string, identityID string) error {
func (keycloak *KeycloakOAuthProvider) updateWITUser(ctx context.Context, request *goa.RequestData, user *account.User, identity *account.Identity, witURL string, identityID string) error {
updateUserPayload := &app.UpdateUsersPayload{
Data: &app.UpdateUserData{
Attributes: &app.UpdateIdentityDataAttributes{
Expand All @@ -859,7 +859,7 @@ func (keycloak *KeycloakOAuthProvider) updateWITUser(ctx context.Context, reques
},
},
}
return keycloak.remoteWITService.UpdateWITUser(ctx, request, updateUserPayload, WITEndpointUserProfile, identityID)
return keycloak.remoteWITService.UpdateWITUser(ctx, request, updateUserPayload, witURL, identityID)
}

func checkApproved(ctx context.Context, profileService UserProfileService, accessToken string, profileEndpoint string) (bool, error) {
Expand Down
28 changes: 14 additions & 14 deletions remoteservice/wit.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import (

// RemoteWITService specifies the behaviour of a remote WIT caller
type RemoteWITService interface {
UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, WITEndpoint string, identityID string) error
GetWITUser(ctx context.Context, req *goa.RequestData, WITEndpointUserProfile string, accessToken *string) (*account.User, *account.Identity, error)
CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, WITEndpoint string, identityID string) error
UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, witURL string, identityID string) error
GetWITUser(ctx context.Context, req *goa.RequestData, witURL string, accessToken *string) (*account.User, *account.Identity, error)
CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, witURL string, identityID string) error
}

type RemoteWITServiceCaller struct{}

// UpdateWITUser updates user in WIT
func (r *RemoteWITServiceCaller) UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, WITEndpoint string, identityID string) error {
func (r *RemoteWITServiceCaller) UpdateWITUser(ctx context.Context, req *goa.RequestData, updatePayload *app.UpdateUsersPayload, witURL string, identityID string) error {

// Using the UpdateUserPayload because it also describes which attribtues are being updated and which are not.
updateUserPayload := &witservice.UpdateUserAsServiceAccountUsersPayload{
Expand All @@ -48,7 +48,7 @@ func (r *RemoteWITServiceCaller) UpdateWITUser(ctx context.Context, req *goa.Req
},
}

remoteWITService, err := CreateSecureRemoteClientAsServiceAccount(ctx, req, WITEndpoint)
remoteWITService, err := CreateSecureRemoteClientAsServiceAccount(ctx, req, witURL)
if err != nil {
return err
}
Expand All @@ -71,7 +71,7 @@ func (r *RemoteWITServiceCaller) UpdateWITUser(ctx context.Context, req *goa.Req
}

// CreateWITUser updates user in WIT
func (r *RemoteWITServiceCaller) CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, WITEndpoint string, identityID string) error {
func (r *RemoteWITServiceCaller) CreateWITUser(ctx context.Context, req *goa.RequestData, user *account.User, identity *account.Identity, witURL string, identityID string) error {
createUserPayload := &witservice.CreateUserAsServiceAccountUsersPayload{
Data: &witservice.CreateUserData{
Attributes: &witservice.CreateIdentityDataAttributes{
Expand All @@ -89,7 +89,7 @@ func (r *RemoteWITServiceCaller) CreateWITUser(ctx context.Context, req *goa.Req
},
}

remoteWITService, err := CreateSecureRemoteClientAsServiceAccount(ctx, req, WITEndpoint)
remoteWITService, err := CreateSecureRemoteClientAsServiceAccount(ctx, req, witURL)
if err != nil {
return err
}
Expand All @@ -113,12 +113,12 @@ func (r *RemoteWITServiceCaller) CreateWITUser(ctx context.Context, req *goa.Req
}

// GetWITUser calls WIT to check if user exists and uses the user's token for authorization and identity ID discovery
func (r *RemoteWITServiceCaller) GetWITUser(ctx context.Context, req *goa.RequestData, WITEndpointUserProfile string, accessToken *string) (*account.User, *account.Identity, error) {
func (r *RemoteWITServiceCaller) GetWITUser(ctx context.Context, req *goa.RequestData, witURL string, accessToken *string) (*account.User, *account.Identity, error) {

var user *account.User
var identity *account.Identity

remoteWITService, err := CreateSecureRemoteWITClient(ctx, req, WITEndpointUserProfile, accessToken)
remoteWITService, err := CreateSecureRemoteWITClient(ctx, req, witURL, accessToken)
res, err := remoteWITService.ShowUser(goasupport.ForwardContextRequestID(ctx), witservice.ShowUserPath(), nil, nil)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -217,12 +217,12 @@ func CreateSecureRemoteWITClient(ctx context.Context, req *goa.RequestData, remo
}

// CreateSecureRemoteClientAsServiceAccount creates a client that would communicate with WIT service using a service account token.
func CreateSecureRemoteClientAsServiceAccount(ctx context.Context, req *goa.RequestData, remoteEndpoint string) (*witservice.Client, error) {
u, err := url.Parse(remoteEndpoint)
func CreateSecureRemoteClientAsServiceAccount(ctx context.Context, req *goa.RequestData, remoteURL string) (*witservice.Client, error) {
u, err := url.Parse(remoteURL)
if err != nil {
log.Error(ctx, map[string]interface{}{
"remote_endpoint": remoteEndpoint,
"err": err,
"remote_url": remoteURL,
"err": err,
}, "unable to parse remote endpoint")
return nil, err
}
Expand All @@ -235,7 +235,7 @@ func CreateSecureRemoteClientAsServiceAccount(ctx context.Context, req *goa.Requ
return nil, err
}
log.Info(ctx, map[string]interface{}{
"remote_endpoint": remoteEndpoint,
"remote_url": remoteURL,
}, "service token generated, will be used to call WIT")
staticToken := goaclient.StaticToken{
Value: serviceAccountToken,
Expand Down

0 comments on commit b184feb

Please sign in to comment.