diff options
Diffstat (limited to 'models/auth')
-rw-r--r-- | models/auth/oauth2.go | 59 | ||||
-rw-r--r-- | models/auth/oauth2_test.go | 3 |
2 files changed, 37 insertions, 25 deletions
diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index 9fdce24253..e42084c086 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -31,9 +31,14 @@ type OAuth2Application struct { Name string ClientID string `xorm:"unique"` ClientSecret string - RedirectURIs []string `xorm:"redirect_uris JSON TEXT"` - CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` - UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + // OAuth defines both Confidential and Public client types + // https://datatracker.ietf.org/doc/html/rfc6749#section-2.1 + // "Authorization servers MUST record the client type in the client registration details" + // https://datatracker.ietf.org/doc/html/rfc8252#section-8.4 + ConfidentialClient bool `xorm:"NOT NULL DEFAULT TRUE"` + RedirectURIs []string `xorm:"redirect_uris JSON TEXT"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } func init() { @@ -57,15 +62,17 @@ func (app *OAuth2Application) PrimaryRedirectURI() string { // ContainsRedirectURI checks if redirectURI is allowed for app func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool { - uri, err := url.Parse(redirectURI) - // ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3 - if err == nil && uri.Scheme == "http" && uri.Port() != "" { - ip := net.ParseIP(uri.Hostname()) - if ip != nil && ip.IsLoopback() { - // strip port - uri.Host = uri.Hostname() - if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) { - return true + if !app.ConfidentialClient { + uri, err := url.Parse(redirectURI) + // ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3 + if err == nil && uri.Scheme == "http" && uri.Port() != "" { + ip := net.ParseIP(uri.Hostname()) + if ip != nil && ip.IsLoopback() { + // strip port + uri.Host = uri.Hostname() + if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) { + return true + } } } } @@ -161,19 +168,21 @@ func GetOAuth2ApplicationsByUserID(ctx context.Context, userID int64) (apps []*O // CreateOAuth2ApplicationOptions holds options to create an oauth2 application type CreateOAuth2ApplicationOptions struct { - Name string - UserID int64 - RedirectURIs []string + Name string + UserID int64 + ConfidentialClient bool + RedirectURIs []string } // CreateOAuth2Application inserts a new oauth2 application func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOptions) (*OAuth2Application, error) { clientID := uuid.New().String() app := &OAuth2Application{ - UID: opts.UserID, - Name: opts.Name, - ClientID: clientID, - RedirectURIs: opts.RedirectURIs, + UID: opts.UserID, + Name: opts.Name, + ClientID: clientID, + RedirectURIs: opts.RedirectURIs, + ConfidentialClient: opts.ConfidentialClient, } if err := db.Insert(ctx, app); err != nil { return nil, err @@ -183,10 +192,11 @@ func CreateOAuth2Application(ctx context.Context, opts CreateOAuth2ApplicationOp // UpdateOAuth2ApplicationOptions holds options to update an oauth2 application type UpdateOAuth2ApplicationOptions struct { - ID int64 - Name string - UserID int64 - RedirectURIs []string + ID int64 + Name string + UserID int64 + ConfidentialClient bool + RedirectURIs []string } // UpdateOAuth2Application updates an oauth2 application @@ -207,6 +217,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic app.Name = opts.Name app.RedirectURIs = opts.RedirectURIs + app.ConfidentialClient = opts.ConfidentialClient if err = updateOAuth2Application(ctx, app); err != nil { return nil, err @@ -217,7 +228,7 @@ func UpdateOAuth2Application(opts UpdateOAuth2ApplicationOptions) (*OAuth2Applic } func updateOAuth2Application(ctx context.Context, app *OAuth2Application) error { - if _, err := db.GetEngine(ctx).ID(app.ID).Update(app); err != nil { + if _, err := db.GetEngine(ctx).ID(app.ID).UseBool("confidential_client").Update(app); err != nil { return err } return nil diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index 3815cb3b2c..7a4df6b9ac 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -45,7 +45,8 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) { app := &auth_model.OAuth2Application{ - RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"}, + RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"}, + ConfidentialClient: false, } // http loopback uris should ignore port |