Skip to content

Commit

Permalink
Merge pull request #388 from MadAppGang/federated-oidc-scope-mapping
Browse files Browse the repository at this point in the history
federated OIDC scope mapping
  • Loading branch information
hummerd authored Feb 27, 2023
2 parents adaf142 + 538c5cf commit 5baefe1
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ FROM golang:1.19.2-alpine3.16 as builder
WORKDIR $GOPATH/src/github.com/madappgang/identifo
COPY . ./
RUN go mod download
RUN go build -o plugins/bin/ github.com/madappgang/identifo/v2/plugins/...
RUN go build -o plugins/bin/ github.com/madappgang/identifo/v2/plugins/...
RUN go build -o /identifo .

FROM alpine:3.13.2
FROM alpine:3.16
RUN apk --no-cache add ca-certificates

WORKDIR /
Expand Down
2 changes: 2 additions & 0 deletions model/oidc_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type OIDCSettings struct {
EmailClaimField string `bson:"email_claim_field,omitempty" json:"email_claim_field,omitempty"`
UserIDClaimField string `bson:"user_id_claim_field,omitempty" json:"user_id_claim_field,omitempty"`
Scopes []string `bson:"scopes,omitempty" json:"scopes,omitempty"`
// ScopeMapping maps OIDC scopes to Identifo scopes.
ScopeMapping map[string]string `bson:"scope_mapping,omitempty" json:"scope_mapping,omitempty"`
}

func (s OIDCSettings) IsValid() error {
Expand Down
49 changes: 49 additions & 0 deletions storage/mongo/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package mongo_test

import (
"os"
"testing"

"github.com/madappgang/identifo/v2/model"
"github.com/madappgang/identifo/v2/storage/mongo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestAppCRUD(t *testing.T) {
if os.Getenv("IDENTIFO_STORAGE_MONGO_TEST_INTEGRATION") == "" {
t.SkipNow()
}

connStr := os.Getenv("IDENTIFO_STORAGE_MONGO_CONN")

s, err := mongo.NewAppStorage(model.MongoDatabaseSettings{
ConnectionString: connStr,
DatabaseName: "test_users",
})
require.NoError(t, err)

expectedApp := model.AppData{
ID: "test_app",
Active: true,
Secret: "test_secret",
OIDCSettings: model.OIDCSettings{
ScopeMapping: map[string]string{
"offline_access": "offline",
},
},
}

app, err := s.CreateApp(expectedApp)
require.NoError(t, err)

defer s.DeleteApp(app.ID)

_, err = s.AppByID(app.ID)
require.NoError(t, err)

assert.Equal(t, app.ID, expectedApp.ID)
assert.Equal(t, app.Active, expectedApp.Active)
assert.Equal(t, app.Secret, expectedApp.Secret)
assert.Equal(t, app.OIDCSettings.ScopeMapping, expectedApp.OIDCSettings.ScopeMapping)
}
11 changes: 10 additions & 1 deletion web/api/federated_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,16 @@ func getCallbackUrl(req *http.Request) string {
}

func getScopes(req *http.Request) []string {
return strings.Split(req.URL.Query().Get("scopes"), ",")
rs := strings.Split(req.URL.Query().Get("scopes"), ",")

result := []string{}
for _, scope := range rs {
if scope != "" {
result = append(result, scope)
}
}

return result
}

func sessionKey(appId, provider string) string {
Expand Down
17 changes: 17 additions & 0 deletions web/api/federated_oidc_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ func (ar *Router) OIDCLoginComplete(w http.ResponseWriter, r *http.Request) {
requestedScopes := fsess.Scopes
requestedScopes = append(requestedScopes, getScopes(r)...)

// map OIDC scopes to Identifo scopes
requestedScopes = mapScopes(app.OIDCSettings.ScopeMapping, requestedScopes)

authResult, err := ar.loginFlow(app, user, requestedScopes)
if err != nil {
ar.Error(w, locale, http.StatusInternalServerError, l.ErrorFederatedLoginError, err)
Expand All @@ -220,6 +223,20 @@ func (ar *Router) OIDCLoginComplete(w http.ResponseWriter, r *http.Request) {
ar.ServeJSON(w, locale, http.StatusOK, authResult)
}

func mapScopes(m map[string]string, scopes []string) []string {
result := make([]string, 0, len(scopes))

for _, s := range scopes {
if mapped, ok := m[s]; ok {
result = append(result, mapped)
} else {
result = append(result, s)
}
}

return result
}

func makeRedirectURL(redirect string, app model.AppData) (string, error) {
u, err := url.Parse(redirect)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion web/api/federated_oidc_login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func Test_Router_OIDCLogin_Redirect(t *testing.T) {

require.Equal(t, http.StatusFound, rw.Code, "should redirect to the provider", rw.Body.String())

expectedAuthURL := oidcServer.URL + "/auth?client_id=test&redirect_uri=http%3A%2F%2Flocalhost%3A8080&response_type=code&scope=openid+&state=test"
expectedAuthURL := oidcServer.URL + "/auth?client_id=test&redirect_uri=http%3A%2F%2Flocalhost%3A8080&response_type=code&scope=openid&state=test"

locURL, err := url.Parse(rw.Header().Get("Location"))
require.NoError(t, err)
Expand Down

0 comments on commit 5baefe1

Please sign in to comment.