Skip to content

Commit 20a854c

Browse files
committed
fixup! Update GitLab IDP to use OIDC instead of OAuth2
1 parent 1365a50 commit 20a854c

File tree

1 file changed

+37
-3
lines changed
  • pkg/oauthserver/oauth/external/gitlab

1 file changed

+37
-3
lines changed

pkg/oauthserver/oauth/external/gitlab/gitlab.go

+37-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package gitlab
22

33
import (
4-
"errors"
4+
"fmt"
55
"net/http"
66
"net/url"
77
"path"
8+
"strconv"
89

910
"github.com/openshift/origin/pkg/oauthserver/oauth/external"
1011
"github.com/openshift/origin/pkg/oauthserver/oauth/external/openid"
@@ -23,7 +24,8 @@ const (
2324
// The ability to authenticate using GitLab, and read-only access to the user's profile information and group memberships
2425
gitlabOIDCScope = "openid"
2526

26-
// An opaque token that uniquely identifies the user
27+
// The ID of the user
28+
// See above comment about GitLab 11.1.0 and the custom IDTokenValidator below
2729
// Along with providerName, builds the identity object's Name field (see Identity.ProviderUserName)
2830
gitlabIDClaim = "sub"
2931
// The user's GitLab username
@@ -41,7 +43,7 @@ func NewProvider(providerName, URL, clientID, clientSecret string, transport htt
4143
// Create service URLs
4244
u, err := url.Parse(URL)
4345
if err != nil {
44-
return nil, errors.New("gitlab host URL is invalid")
46+
return nil, fmt.Errorf("gitlab host URL %q is invalid", URL)
4547
}
4648

4749
config := openid.Config{
@@ -58,6 +60,22 @@ func NewProvider(providerName, URL, clientID, clientSecret string, transport htt
5860
PreferredUsernameClaims: []string{gitlabPreferredUsernameClaim},
5961
EmailClaims: []string{gitlabEmailClaim},
6062
NameClaims: []string{gitlabDisplayNameClaim},
63+
64+
// make sure that gitlabIDClaim is a valid uint64, see above comment about GitLab 11.1.0
65+
IDTokenValidator: func(idTokenClaims map[string]interface{}) error {
66+
gitlabID, ok := idTokenClaims[gitlabIDClaim].(string)
67+
if !ok {
68+
return nil // this is an OIDC spec violation which is handled by the default code path
69+
}
70+
if isPossibleSHA256HexDigest(gitlabID) {
71+
return fmt.Errorf("incompatible gitlab IDP, ID claim %s=%s is SHA256 hex digest instead of digit",
72+
gitlabIDClaim, gitlabID)
73+
}
74+
if !isValidUint64(gitlabID, 10) {
75+
return fmt.Errorf("invalid gitlab IDP, ID claim %s=%s is not a digit", gitlabIDClaim, gitlabID)
76+
}
77+
return nil
78+
},
6179
}
6280

6381
return openid.NewProvider(providerName, transport, config)
@@ -67,3 +85,19 @@ func appendPath(u url.URL, subpath string) string {
6785
u.Path = path.Join(u.Path, subpath)
6886
return u.String()
6987
}
88+
89+
func isPossibleSHA256HexDigest(s string) bool {
90+
const (
91+
// Have 256 bits from hex digest
92+
// In hexadecimal each digit encodes 4 bits
93+
// Thus we need 64 digits to represent 256 bits
94+
sha256Len = 256 / 4
95+
hexBase = 16
96+
)
97+
return len(s) == sha256Len && isValidUint64(s, hexBase)
98+
}
99+
100+
func isValidUint64(s string, base int) bool {
101+
_, err := strconv.ParseUint(s, base, 64)
102+
return err == nil
103+
}

0 commit comments

Comments
 (0)