mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-04-08 06:47:55 +00:00
fix: review comments
This commit is contained in:
@@ -1,2 +1 @@
|
|||||||
ALTER TABLE "oidc_codes" DROP COLUMN "code_challenge";
|
ALTER TABLE "oidc_codes" DROP COLUMN "code_challenge";
|
||||||
ALTER TABLE "oidc_codes" DROP COLUMN "code_challenge_method";
|
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
ALTER TABLE "oidc_codes" ADD COLUMN "code_challenge" TEXT DEFAULT "";
|
ALTER TABLE "oidc_codes" ADD COLUMN "code_challenge" TEXT DEFAULT "";
|
||||||
ALTER TABLE "oidc_codes" ADD COLUMN "code_challenge_method" TEXT DEFAULT "";
|
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import (
|
|||||||
"github.com/steveiliop56/tinyauth/internal/config"
|
"github.com/steveiliop56/tinyauth/internal/config"
|
||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
"github.com/steveiliop56/tinyauth/internal/utils"
|
"github.com/steveiliop56/tinyauth/internal/utils"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContextController(t *testing.T) {
|
func TestContextController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
controllerConfig := controller.ContextControllerConfig{
|
controllerConfig := controller.ContextControllerConfig{
|
||||||
Providers: []controller.Provider{
|
Providers: []controller.Provider{
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHealthController(t *testing.T) {
|
func TestHealthController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
description string
|
description string
|
||||||
path string
|
path string
|
||||||
|
|||||||
@@ -309,7 +309,8 @@ func (controller *OIDCController) Token(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := controller.oidc.ValidatePKCE(entry.CodeChallenge, entry.CodeChallengeMethod, req.CodeVerifier)
|
tlog.App.Debug().Str("challenge", entry.CodeChallenge).Str("verifier", req.CodeVerifier).Msg("Validating PKCE")
|
||||||
|
ok := controller.oidc.ValidatePKCE(entry.CodeChallenge, req.CodeVerifier)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
tlog.App.Warn().Msg("PKCE validation failed")
|
tlog.App.Warn().Msg("PKCE validation failed")
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ import (
|
|||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
"github.com/steveiliop56/tinyauth/internal/repository"
|
"github.com/steveiliop56/tinyauth/internal/repository"
|
||||||
"github.com/steveiliop56/tinyauth/internal/service"
|
"github.com/steveiliop56/tinyauth/internal/service"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestOIDCController(t *testing.T) {
|
func TestOIDCController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
oidcServiceCfg := service.OIDCServiceConfig{
|
oidcServiceCfg := service.OIDCServiceConfig{
|
||||||
@@ -473,6 +475,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
assert.NotEmpty(t, code)
|
assert.NotEmpty(t, code)
|
||||||
|
|
||||||
// Now exchange the code for a token
|
// Now exchange the code for a token
|
||||||
|
recorder = httptest.NewRecorder()
|
||||||
tokenReqBody := controller.TokenRequest{
|
tokenReqBody := controller.TokenRequest{
|
||||||
GrantType: "authorization_code",
|
GrantType: "authorization_code",
|
||||||
Code: code,
|
Code: code,
|
||||||
@@ -499,7 +502,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
hasher.Write([]byte("some-challenge"))
|
hasher.Write([]byte("some-challenge"))
|
||||||
codeChallenge := hasher.Sum(nil)
|
codeChallenge := hasher.Sum(nil)
|
||||||
codeChallengeEncoded := base64.URLEncoding.EncodeToString(codeChallenge)
|
codeChallengeEncoded := base64.RawURLEncoding.EncodeToString(codeChallenge)
|
||||||
reqBody := service.AuthorizeRequest{
|
reqBody := service.AuthorizeRequest{
|
||||||
Scope: "openid",
|
Scope: "openid",
|
||||||
ResponseType: "code",
|
ResponseType: "code",
|
||||||
@@ -533,6 +536,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
assert.NotEmpty(t, code)
|
assert.NotEmpty(t, code)
|
||||||
|
|
||||||
// Now exchange the code for a token
|
// Now exchange the code for a token
|
||||||
|
recorder = httptest.NewRecorder()
|
||||||
tokenReqBody := controller.TokenRequest{
|
tokenReqBody := controller.TokenRequest{
|
||||||
GrantType: "authorization_code",
|
GrantType: "authorization_code",
|
||||||
Code: code,
|
Code: code,
|
||||||
@@ -559,7 +563,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
hasher.Write([]byte("some-challenge"))
|
hasher.Write([]byte("some-challenge"))
|
||||||
codeChallenge := hasher.Sum(nil)
|
codeChallenge := hasher.Sum(nil)
|
||||||
codeChallengeEncoded := base64.URLEncoding.EncodeToString(codeChallenge)
|
codeChallengeEncoded := base64.RawURLEncoding.EncodeToString(codeChallenge)
|
||||||
reqBody := service.AuthorizeRequest{
|
reqBody := service.AuthorizeRequest{
|
||||||
Scope: "openid",
|
Scope: "openid",
|
||||||
ResponseType: "code",
|
ResponseType: "code",
|
||||||
@@ -593,6 +597,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
assert.NotEmpty(t, code)
|
assert.NotEmpty(t, code)
|
||||||
|
|
||||||
// Now exchange the code for a token
|
// Now exchange the code for a token
|
||||||
|
recorder = httptest.NewRecorder()
|
||||||
tokenReqBody := controller.TokenRequest{
|
tokenReqBody := controller.TokenRequest{
|
||||||
GrantType: "authorization_code",
|
GrantType: "authorization_code",
|
||||||
Code: code,
|
Code: code,
|
||||||
@@ -607,7 +612,7 @@ func TestOIDCController(t *testing.T) {
|
|||||||
req.SetBasicAuth("some-client-id", "some-client-secret")
|
req.SetBasicAuth("some-client-id", "some-client-secret")
|
||||||
router.ServeHTTP(recorder, req)
|
router.ServeHTTP(recorder, req)
|
||||||
|
|
||||||
assert.Equal(t, 200, recorder.Code)
|
assert.Equal(t, 400, recorder.Code)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestProxyController(t *testing.T) {
|
func TestProxyController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
authServiceCfg := service.AuthServiceConfig{
|
authServiceCfg := service.AuthServiceConfig{
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestResourcesController(t *testing.T) {
|
func TestResourcesController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
resourcesControllerCfg := controller.ResourcesControllerConfig{
|
resourcesControllerCfg := controller.ResourcesControllerConfig{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestUserController(t *testing.T) {
|
func TestUserController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
authServiceCfg := service.AuthServiceConfig{
|
authServiceCfg := service.AuthServiceConfig{
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ import (
|
|||||||
"github.com/steveiliop56/tinyauth/internal/controller"
|
"github.com/steveiliop56/tinyauth/internal/controller"
|
||||||
"github.com/steveiliop56/tinyauth/internal/repository"
|
"github.com/steveiliop56/tinyauth/internal/repository"
|
||||||
"github.com/steveiliop56/tinyauth/internal/service"
|
"github.com/steveiliop56/tinyauth/internal/service"
|
||||||
|
"github.com/steveiliop56/tinyauth/internal/utils/tlog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWellKnownController(t *testing.T) {
|
func TestWellKnownController(t *testing.T) {
|
||||||
|
tlog.NewTestLogger().Init()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
oidcServiceCfg := service.OIDCServiceConfig{
|
oidcServiceCfg := service.OIDCServiceConfig{
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ type OidcCode struct {
|
|||||||
ExpiresAt int64
|
ExpiresAt int64
|
||||||
Nonce string
|
Nonce string
|
||||||
CodeChallenge string
|
CodeChallenge string
|
||||||
CodeChallengeMethod string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type OidcToken struct {
|
type OidcToken struct {
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ INSERT INTO "oidc_codes" (
|
|||||||
"client_id",
|
"client_id",
|
||||||
"expires_at",
|
"expires_at",
|
||||||
"nonce",
|
"nonce",
|
||||||
"code_challenge",
|
"code_challenge"
|
||||||
"code_challenge_method"
|
|
||||||
) VALUES (
|
) VALUES (
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?
|
?, ?, ?, ?, ?, ?, ?, ?
|
||||||
)
|
)
|
||||||
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method
|
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateOidcCodeParams struct {
|
type CreateOidcCodeParams struct {
|
||||||
@@ -35,7 +34,6 @@ type CreateOidcCodeParams struct {
|
|||||||
ExpiresAt int64
|
ExpiresAt int64
|
||||||
Nonce string
|
Nonce string
|
||||||
CodeChallenge string
|
CodeChallenge string
|
||||||
CodeChallengeMethod string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateOidcCode(ctx context.Context, arg CreateOidcCodeParams) (OidcCode, error) {
|
func (q *Queries) CreateOidcCode(ctx context.Context, arg CreateOidcCodeParams) (OidcCode, error) {
|
||||||
@@ -48,7 +46,6 @@ func (q *Queries) CreateOidcCode(ctx context.Context, arg CreateOidcCodeParams)
|
|||||||
arg.ExpiresAt,
|
arg.ExpiresAt,
|
||||||
arg.Nonce,
|
arg.Nonce,
|
||||||
arg.CodeChallenge,
|
arg.CodeChallenge,
|
||||||
arg.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
var i OidcCode
|
var i OidcCode
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@@ -60,7 +57,6 @@ func (q *Queries) CreateOidcCode(ctx context.Context, arg CreateOidcCodeParams)
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -164,7 +160,7 @@ func (q *Queries) CreateOidcUserInfo(ctx context.Context, arg CreateOidcUserInfo
|
|||||||
const deleteExpiredOidcCodes = `-- name: DeleteExpiredOidcCodes :many
|
const deleteExpiredOidcCodes = `-- name: DeleteExpiredOidcCodes :many
|
||||||
DELETE FROM "oidc_codes"
|
DELETE FROM "oidc_codes"
|
||||||
WHERE "expires_at" < ?
|
WHERE "expires_at" < ?
|
||||||
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method
|
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) DeleteExpiredOidcCodes(ctx context.Context, expiresAt int64) ([]OidcCode, error) {
|
func (q *Queries) DeleteExpiredOidcCodes(ctx context.Context, expiresAt int64) ([]OidcCode, error) {
|
||||||
@@ -185,7 +181,6 @@ func (q *Queries) DeleteExpiredOidcCodes(ctx context.Context, expiresAt int64) (
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -296,7 +291,7 @@ func (q *Queries) DeleteOidcUserInfo(ctx context.Context, sub string) error {
|
|||||||
const getOidcCode = `-- name: GetOidcCode :one
|
const getOidcCode = `-- name: GetOidcCode :one
|
||||||
DELETE FROM "oidc_codes"
|
DELETE FROM "oidc_codes"
|
||||||
WHERE "code_hash" = ?
|
WHERE "code_hash" = ?
|
||||||
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method
|
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetOidcCode(ctx context.Context, codeHash string) (OidcCode, error) {
|
func (q *Queries) GetOidcCode(ctx context.Context, codeHash string) (OidcCode, error) {
|
||||||
@@ -311,7 +306,6 @@ func (q *Queries) GetOidcCode(ctx context.Context, codeHash string) (OidcCode, e
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@@ -319,7 +313,7 @@ func (q *Queries) GetOidcCode(ctx context.Context, codeHash string) (OidcCode, e
|
|||||||
const getOidcCodeBySub = `-- name: GetOidcCodeBySub :one
|
const getOidcCodeBySub = `-- name: GetOidcCodeBySub :one
|
||||||
DELETE FROM "oidc_codes"
|
DELETE FROM "oidc_codes"
|
||||||
WHERE "sub" = ?
|
WHERE "sub" = ?
|
||||||
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method
|
RETURNING sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetOidcCodeBySub(ctx context.Context, sub string) (OidcCode, error) {
|
func (q *Queries) GetOidcCodeBySub(ctx context.Context, sub string) (OidcCode, error) {
|
||||||
@@ -334,13 +328,12 @@ func (q *Queries) GetOidcCodeBySub(ctx context.Context, sub string) (OidcCode, e
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOidcCodeBySubUnsafe = `-- name: GetOidcCodeBySubUnsafe :one
|
const getOidcCodeBySubUnsafe = `-- name: GetOidcCodeBySubUnsafe :one
|
||||||
SELECT sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method FROM "oidc_codes"
|
SELECT sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge FROM "oidc_codes"
|
||||||
WHERE "sub" = ?
|
WHERE "sub" = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -356,13 +349,12 @@ func (q *Queries) GetOidcCodeBySubUnsafe(ctx context.Context, sub string) (OidcC
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOidcCodeUnsafe = `-- name: GetOidcCodeUnsafe :one
|
const getOidcCodeUnsafe = `-- name: GetOidcCodeUnsafe :one
|
||||||
SELECT sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge, code_challenge_method FROM "oidc_codes"
|
SELECT sub, code_hash, scope, redirect_uri, client_id, expires_at, nonce, code_challenge FROM "oidc_codes"
|
||||||
WHERE "code_hash" = ?
|
WHERE "code_hash" = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -378,7 +370,6 @@ func (q *Queries) GetOidcCodeUnsafe(ctx context.Context, codeHash string) (OidcC
|
|||||||
&i.ExpiresAt,
|
&i.ExpiresAt,
|
||||||
&i.Nonce,
|
&i.Nonce,
|
||||||
&i.CodeChallenge,
|
&i.CodeChallenge,
|
||||||
&i.CodeChallengeMethod,
|
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ func (service *OIDCService) ValidateAuthorizeParams(req AuthorizeRequest) error
|
|||||||
|
|
||||||
// PKCE code challenge method if set
|
// PKCE code challenge method if set
|
||||||
if req.CodeChallenge != "" && req.CodeChallengeMethod != "" {
|
if req.CodeChallenge != "" && req.CodeChallengeMethod != "" {
|
||||||
if req.CodeChallengeMethod != "S256" || req.CodeChallenge == "plain" {
|
if req.CodeChallengeMethod != "S256" && req.CodeChallengeMethod != "plain" {
|
||||||
return errors.New("invalid_request")
|
return errors.New("invalid_request")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,10 +329,8 @@ func (service *OIDCService) StoreCode(c *gin.Context, sub string, code string, r
|
|||||||
if req.CodeChallenge != "" {
|
if req.CodeChallenge != "" {
|
||||||
if req.CodeChallengeMethod == "S256" {
|
if req.CodeChallengeMethod == "S256" {
|
||||||
entry.CodeChallenge = req.CodeChallenge
|
entry.CodeChallenge = req.CodeChallenge
|
||||||
entry.CodeChallengeMethod = "S256"
|
|
||||||
} else {
|
} else {
|
||||||
entry.CodeChallenge = service.hashAndEncodePKCE(req.CodeChallenge)
|
entry.CodeChallenge = service.hashAndEncodePKCE(req.CodeChallenge)
|
||||||
entry.CodeChallengeMethod = "plain"
|
|
||||||
tlog.App.Warn().Msg("Received plain PKCE code challenge, it's recommended to use S256 for better security")
|
tlog.App.Warn().Msg("Received plain PKCE code challenge, it's recommended to use S256 for better security")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -751,19 +749,15 @@ func (service *OIDCService) GetJWK() ([]byte, error) {
|
|||||||
return jwk.Public().MarshalJSON()
|
return jwk.Public().MarshalJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *OIDCService) ValidatePKCE(codeChallenge string, codeChallengeMethod string, codeVerifier string) bool {
|
func (service *OIDCService) ValidatePKCE(codeChallenge string, codeVerifier string) bool {
|
||||||
if codeChallenge == "" {
|
if codeChallenge == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if codeChallengeMethod == "plain" {
|
|
||||||
// Code challenge is hashed and encoded in the database for security reasons
|
|
||||||
return codeChallenge == service.hashAndEncodePKCE(codeVerifier)
|
return codeChallenge == service.hashAndEncodePKCE(codeVerifier)
|
||||||
}
|
}
|
||||||
return codeChallenge == codeVerifier
|
|
||||||
}
|
|
||||||
|
|
||||||
func (service *OIDCService) hashAndEncodePKCE(codeVerifier string) string {
|
func (service *OIDCService) hashAndEncodePKCE(codeVerifier string) string {
|
||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
hasher.Write([]byte(codeVerifier))
|
hasher.Write([]byte(codeVerifier))
|
||||||
return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
|
return base64.RawURLEncoding.EncodeToString(hasher.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,17 @@ func NewSimpleLogger() *Logger {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTestLogger() *Logger {
|
||||||
|
return NewLogger(config.LogConfig{
|
||||||
|
Level: "trace",
|
||||||
|
Streams: config.LogStreams{
|
||||||
|
HTTP: config.LogStreamConfig{Enabled: true},
|
||||||
|
App: config.LogStreamConfig{Enabled: true},
|
||||||
|
Audit: config.LogStreamConfig{Enabled: true},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Logger) Init() {
|
func (l *Logger) Init() {
|
||||||
Audit = l.Audit
|
Audit = l.Audit
|
||||||
HTTP = l.HTTP
|
HTTP = l.HTTP
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ INSERT INTO "oidc_codes" (
|
|||||||
"client_id",
|
"client_id",
|
||||||
"expires_at",
|
"expires_at",
|
||||||
"nonce",
|
"nonce",
|
||||||
"code_challenge",
|
"code_challenge"
|
||||||
"code_challenge_method"
|
|
||||||
) VALUES (
|
) VALUES (
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?
|
?, ?, ?, ?, ?, ?, ?, ?
|
||||||
)
|
)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ CREATE TABLE IF NOT EXISTS "oidc_codes" (
|
|||||||
"client_id" TEXT NOT NULL,
|
"client_id" TEXT NOT NULL,
|
||||||
"expires_at" INTEGER NOT NULL,
|
"expires_at" INTEGER NOT NULL,
|
||||||
"nonce" TEXT DEFAULT "",
|
"nonce" TEXT DEFAULT "",
|
||||||
"code_challenge" TEXT DEFAULT "",
|
"code_challenge" TEXT DEFAULT ""
|
||||||
"code_challenge_method" TEXT DEFAULT ""
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "oidc_tokens" (
|
CREATE TABLE IF NOT EXISTS "oidc_tokens" (
|
||||||
|
|||||||
Reference in New Issue
Block a user