Add HMAC protection on /approval endpoint
Signed-off-by: Bob Callaway <bcallaway@google.com>
This commit is contained in:
parent
454122ca22
commit
fcfbb1ecb0
@ -1,6 +1,7 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@ -499,7 +500,13 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
|
|||||||
s.logger.Infof("login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q",
|
s.logger.Infof("login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q",
|
||||||
authReq.ConnectorID, claims.Username, claims.PreferredUsername, email, claims.Groups)
|
authReq.ConnectorID, claims.Username, claims.PreferredUsername, email, claims.Groups)
|
||||||
|
|
||||||
returnURL := path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID
|
// TODO: if s.skipApproval or !authReq.ForceApprovalPrompt, we can skip the redirect to /approval and go ahead and send code
|
||||||
|
|
||||||
|
h := hmac.New(sha256.New, authReq.HMACKey)
|
||||||
|
h.Write([]byte(authReq.ID))
|
||||||
|
mac := h.Sum(nil)
|
||||||
|
|
||||||
|
returnURL := path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID + "&hmac=" + base64.RawURLEncoding.EncodeToString(mac)
|
||||||
_, ok := conn.(connector.RefreshConnector)
|
_, ok := conn.(connector.RefreshConnector)
|
||||||
if !ok {
|
if !ok {
|
||||||
return returnURL, nil
|
return returnURL, nil
|
||||||
@ -544,6 +551,17 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
||||||
|
macEncoded := r.FormValue("hmac")
|
||||||
|
if macEncoded == "" {
|
||||||
|
s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mac, err := base64.RawURLEncoding.DecodeString(macEncoded)
|
||||||
|
if err != nil {
|
||||||
|
s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
authReq, err := s.storage.GetAuthRequest(r.FormValue("req"))
|
authReq, err := s.storage.GetAuthRequest(r.FormValue("req"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Errorf("Failed to get auth request: %v", err)
|
s.logger.Errorf("Failed to get auth request: %v", err)
|
||||||
@ -556,6 +574,16 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build expected hmac with secret key
|
||||||
|
h := hmac.New(sha256.New, authReq.HMACKey)
|
||||||
|
h.Write([]byte(r.FormValue("req")))
|
||||||
|
expectedMAC := h.Sum(nil)
|
||||||
|
// constant time comparison
|
||||||
|
if !hmac.Equal(mac, expectedMAC) {
|
||||||
|
s.renderError(r, w, http.StatusUnauthorized, "Unauthorized request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
if s.skipApproval {
|
if s.skipApproval {
|
||||||
|
@ -2,6 +2,7 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
@ -576,6 +577,7 @@ func (s *Server) parseAuthorizationRequest(r *http.Request) (*storage.AuthReques
|
|||||||
CodeChallenge: codeChallenge,
|
CodeChallenge: codeChallenge,
|
||||||
CodeChallengeMethod: codeChallengeMethod,
|
CodeChallengeMethod: codeChallengeMethod,
|
||||||
},
|
},
|
||||||
|
HMACKey: storage.NewHMACKey(crypto.SHA256),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) {
|
|||||||
Groups: []string{"a", "b"},
|
Groups: []string{"a", "b"},
|
||||||
},
|
},
|
||||||
PKCE: codeChallenge,
|
PKCE: codeChallenge,
|
||||||
|
HMACKey: []byte("hmac_key"),
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := storage.Claims{Email: "foobar"}
|
identity := storage.Claims{Email: "foobar"}
|
||||||
@ -137,6 +138,7 @@ func testAuthRequestCRUD(t *testing.T, s storage.Storage) {
|
|||||||
EmailVerified: true,
|
EmailVerified: true,
|
||||||
Groups: []string{"a"},
|
Groups: []string{"a"},
|
||||||
},
|
},
|
||||||
|
HMACKey: []byte("hmac_key"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.CreateAuthRequest(a2); err != nil {
|
if err := s.CreateAuthRequest(a2); err != nil {
|
||||||
@ -817,6 +819,7 @@ func testGC(t *testing.T, s storage.Storage) {
|
|||||||
EmailVerified: true,
|
EmailVerified: true,
|
||||||
Groups: []string{"a", "b"},
|
Groups: []string{"a", "b"},
|
||||||
},
|
},
|
||||||
|
HMACKey: []byte("hmac_key"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.CreateAuthRequest(a); err != nil {
|
if err := s.CreateAuthRequest(a); err != nil {
|
||||||
|
@ -31,6 +31,7 @@ func (d *Database) CreateAuthRequest(authRequest storage.AuthRequest) error {
|
|||||||
SetExpiry(authRequest.Expiry.UTC()).
|
SetExpiry(authRequest.Expiry.UTC()).
|
||||||
SetConnectorID(authRequest.ConnectorID).
|
SetConnectorID(authRequest.ConnectorID).
|
||||||
SetConnectorData(authRequest.ConnectorData).
|
SetConnectorData(authRequest.ConnectorData).
|
||||||
|
SetHmacKey(authRequest.HMACKey).
|
||||||
Save(context.TODO())
|
Save(context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return convertDBError("create auth request: %w", err)
|
return convertDBError("create auth request: %w", err)
|
||||||
@ -94,6 +95,7 @@ func (d *Database) UpdateAuthRequest(id string, updater func(old storage.AuthReq
|
|||||||
SetExpiry(newAuthRequest.Expiry.UTC()).
|
SetExpiry(newAuthRequest.Expiry.UTC()).
|
||||||
SetConnectorID(newAuthRequest.ConnectorID).
|
SetConnectorID(newAuthRequest.ConnectorID).
|
||||||
SetConnectorData(newAuthRequest.ConnectorData).
|
SetConnectorData(newAuthRequest.ConnectorData).
|
||||||
|
SetHmacKey(newAuthRequest.HMACKey).
|
||||||
Save(context.TODO())
|
Save(context.TODO())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rollback(tx, "update auth request uploading: %w", err)
|
return rollback(tx, "update auth request uploading: %w", err)
|
||||||
|
@ -45,6 +45,7 @@ func toStorageAuthRequest(a *db.AuthRequest) storage.AuthRequest {
|
|||||||
CodeChallenge: a.CodeChallenge,
|
CodeChallenge: a.CodeChallenge,
|
||||||
CodeChallengeMethod: a.CodeChallengeMethod,
|
CodeChallengeMethod: a.CodeChallengeMethod,
|
||||||
},
|
},
|
||||||
|
HMACKey: a.HmacKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ type AuthRequest struct {
|
|||||||
CodeChallenge string `json:"code_challenge,omitempty"`
|
CodeChallenge string `json:"code_challenge,omitempty"`
|
||||||
// CodeChallengeMethod holds the value of the "code_challenge_method" field.
|
// CodeChallengeMethod holds the value of the "code_challenge_method" field.
|
||||||
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
||||||
|
// HmacKey holds the value of the "hmac_key" field.
|
||||||
|
HmacKey []byte `json:"hmac_key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// scanValues returns the types for scanning values from sql.Rows.
|
// scanValues returns the types for scanning values from sql.Rows.
|
||||||
@ -62,7 +64,7 @@ func (*AuthRequest) scanValues(columns []string) ([]interface{}, error) {
|
|||||||
values := make([]interface{}, len(columns))
|
values := make([]interface{}, len(columns))
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case authrequest.FieldScopes, authrequest.FieldResponseTypes, authrequest.FieldClaimsGroups, authrequest.FieldConnectorData:
|
case authrequest.FieldScopes, authrequest.FieldResponseTypes, authrequest.FieldClaimsGroups, authrequest.FieldConnectorData, authrequest.FieldHmacKey:
|
||||||
values[i] = new([]byte)
|
values[i] = new([]byte)
|
||||||
case authrequest.FieldForceApprovalPrompt, authrequest.FieldLoggedIn, authrequest.FieldClaimsEmailVerified:
|
case authrequest.FieldForceApprovalPrompt, authrequest.FieldLoggedIn, authrequest.FieldClaimsEmailVerified:
|
||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
@ -211,6 +213,12 @@ func (ar *AuthRequest) assignValues(columns []string, values []interface{}) erro
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
ar.CodeChallengeMethod = value.String
|
ar.CodeChallengeMethod = value.String
|
||||||
}
|
}
|
||||||
|
case authrequest.FieldHmacKey:
|
||||||
|
if value, ok := values[i].(*[]byte); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field hmac_key", values[i])
|
||||||
|
} else if value != nil {
|
||||||
|
ar.HmacKey = *value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -279,6 +287,8 @@ func (ar *AuthRequest) String() string {
|
|||||||
builder.WriteString(ar.CodeChallenge)
|
builder.WriteString(ar.CodeChallenge)
|
||||||
builder.WriteString(", code_challenge_method=")
|
builder.WriteString(", code_challenge_method=")
|
||||||
builder.WriteString(ar.CodeChallengeMethod)
|
builder.WriteString(ar.CodeChallengeMethod)
|
||||||
|
builder.WriteString(", hmac_key=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", ar.HmacKey))
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,8 @@ const (
|
|||||||
FieldCodeChallenge = "code_challenge"
|
FieldCodeChallenge = "code_challenge"
|
||||||
// FieldCodeChallengeMethod holds the string denoting the code_challenge_method field in the database.
|
// FieldCodeChallengeMethod holds the string denoting the code_challenge_method field in the database.
|
||||||
FieldCodeChallengeMethod = "code_challenge_method"
|
FieldCodeChallengeMethod = "code_challenge_method"
|
||||||
|
// FieldHmacKey holds the string denoting the hmac_key field in the database.
|
||||||
|
FieldHmacKey = "hmac_key"
|
||||||
// Table holds the table name of the authrequest in the database.
|
// Table holds the table name of the authrequest in the database.
|
||||||
Table = "auth_requests"
|
Table = "auth_requests"
|
||||||
)
|
)
|
||||||
@ -71,6 +73,7 @@ var Columns = []string{
|
|||||||
FieldExpiry,
|
FieldExpiry,
|
||||||
FieldCodeChallenge,
|
FieldCodeChallenge,
|
||||||
FieldCodeChallengeMethod,
|
FieldCodeChallengeMethod,
|
||||||
|
FieldHmacKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||||
|
@ -204,6 +204,13 @@ func CodeChallengeMethod(v string) predicate.AuthRequest {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HmacKey applies equality check predicate on the "hmac_key" field. It's identical to HmacKeyEQ.
|
||||||
|
func HmacKey(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.EQ(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ClientIDEQ applies the EQ predicate on the "client_id" field.
|
// ClientIDEQ applies the EQ predicate on the "client_id" field.
|
||||||
func ClientIDEQ(v string) predicate.AuthRequest {
|
func ClientIDEQ(v string) predicate.AuthRequest {
|
||||||
return predicate.AuthRequest(func(s *sql.Selector) {
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
@ -1675,6 +1682,82 @@ func CodeChallengeMethodContainsFold(v string) predicate.AuthRequest {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HmacKeyEQ applies the EQ predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyEQ(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.EQ(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyNEQ applies the NEQ predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyNEQ(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.NEQ(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyIn applies the In predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyIn(vs ...[]byte) predicate.AuthRequest {
|
||||||
|
v := make([]interface{}, len(vs))
|
||||||
|
for i := range v {
|
||||||
|
v[i] = vs[i]
|
||||||
|
}
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
// if not arguments were provided, append the FALSE constants,
|
||||||
|
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||||
|
if len(v) == 0 {
|
||||||
|
s.Where(sql.False())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Where(sql.In(s.C(FieldHmacKey), v...))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyNotIn applies the NotIn predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyNotIn(vs ...[]byte) predicate.AuthRequest {
|
||||||
|
v := make([]interface{}, len(vs))
|
||||||
|
for i := range v {
|
||||||
|
v[i] = vs[i]
|
||||||
|
}
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
// if not arguments were provided, append the FALSE constants,
|
||||||
|
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||||
|
if len(v) == 0 {
|
||||||
|
s.Where(sql.False())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.Where(sql.NotIn(s.C(FieldHmacKey), v...))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyGT applies the GT predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyGT(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.GT(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyGTE applies the GTE predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyGTE(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.GTE(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyLT applies the LT predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyLT(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.LT(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKeyLTE applies the LTE predicate on the "hmac_key" field.
|
||||||
|
func HmacKeyLTE(v []byte) predicate.AuthRequest {
|
||||||
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.LTE(s.C(FieldHmacKey), v))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// And groups predicates with the AND operator between them.
|
// And groups predicates with the AND operator between them.
|
||||||
func And(predicates ...predicate.AuthRequest) predicate.AuthRequest {
|
func And(predicates ...predicate.AuthRequest) predicate.AuthRequest {
|
||||||
return predicate.AuthRequest(func(s *sql.Selector) {
|
return predicate.AuthRequest(func(s *sql.Selector) {
|
||||||
|
@ -158,6 +158,12 @@ func (arc *AuthRequestCreate) SetNillableCodeChallengeMethod(s *string) *AuthReq
|
|||||||
return arc
|
return arc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHmacKey sets the "hmac_key" field.
|
||||||
|
func (arc *AuthRequestCreate) SetHmacKey(b []byte) *AuthRequestCreate {
|
||||||
|
arc.mutation.SetHmacKey(b)
|
||||||
|
return arc
|
||||||
|
}
|
||||||
|
|
||||||
// SetID sets the "id" field.
|
// SetID sets the "id" field.
|
||||||
func (arc *AuthRequestCreate) SetID(s string) *AuthRequestCreate {
|
func (arc *AuthRequestCreate) SetID(s string) *AuthRequestCreate {
|
||||||
arc.mutation.SetID(s)
|
arc.mutation.SetID(s)
|
||||||
@ -296,6 +302,9 @@ func (arc *AuthRequestCreate) check() error {
|
|||||||
if _, ok := arc.mutation.CodeChallengeMethod(); !ok {
|
if _, ok := arc.mutation.CodeChallengeMethod(); !ok {
|
||||||
return &ValidationError{Name: "code_challenge_method", err: errors.New(`db: missing required field "AuthRequest.code_challenge_method"`)}
|
return &ValidationError{Name: "code_challenge_method", err: errors.New(`db: missing required field "AuthRequest.code_challenge_method"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := arc.mutation.HmacKey(); !ok {
|
||||||
|
return &ValidationError{Name: "hmac_key", err: errors.New(`db: missing required field "AuthRequest.hmac_key"`)}
|
||||||
|
}
|
||||||
if v, ok := arc.mutation.ID(); ok {
|
if v, ok := arc.mutation.ID(); ok {
|
||||||
if err := authrequest.IDValidator(v); err != nil {
|
if err := authrequest.IDValidator(v); err != nil {
|
||||||
return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "AuthRequest.id": %w`, err)}
|
return &ValidationError{Name: "id", err: fmt.Errorf(`db: validator failed for field "AuthRequest.id": %w`, err)}
|
||||||
@ -489,6 +498,14 @@ func (arc *AuthRequestCreate) createSpec() (*AuthRequest, *sqlgraph.CreateSpec)
|
|||||||
})
|
})
|
||||||
_node.CodeChallengeMethod = value
|
_node.CodeChallengeMethod = value
|
||||||
}
|
}
|
||||||
|
if value, ok := arc.mutation.HmacKey(); ok {
|
||||||
|
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBytes,
|
||||||
|
Value: value,
|
||||||
|
Column: authrequest.FieldHmacKey,
|
||||||
|
})
|
||||||
|
_node.HmacKey = value
|
||||||
|
}
|
||||||
return _node, _spec
|
return _node, _spec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +190,12 @@ func (aru *AuthRequestUpdate) SetNillableCodeChallengeMethod(s *string) *AuthReq
|
|||||||
return aru
|
return aru
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHmacKey sets the "hmac_key" field.
|
||||||
|
func (aru *AuthRequestUpdate) SetHmacKey(b []byte) *AuthRequestUpdate {
|
||||||
|
aru.mutation.SetHmacKey(b)
|
||||||
|
return aru
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the AuthRequestMutation object of the builder.
|
// Mutation returns the AuthRequestMutation object of the builder.
|
||||||
func (aru *AuthRequestUpdate) Mutation() *AuthRequestMutation {
|
func (aru *AuthRequestUpdate) Mutation() *AuthRequestMutation {
|
||||||
return aru.mutation
|
return aru.mutation
|
||||||
@ -424,6 +430,13 @@ func (aru *AuthRequestUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
|||||||
Column: authrequest.FieldCodeChallengeMethod,
|
Column: authrequest.FieldCodeChallengeMethod,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if value, ok := aru.mutation.HmacKey(); ok {
|
||||||
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBytes,
|
||||||
|
Value: value,
|
||||||
|
Column: authrequest.FieldHmacKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
if n, err = sqlgraph.UpdateNodes(ctx, aru.driver, _spec); err != nil {
|
if n, err = sqlgraph.UpdateNodes(ctx, aru.driver, _spec); err != nil {
|
||||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
err = &NotFoundError{authrequest.Label}
|
err = &NotFoundError{authrequest.Label}
|
||||||
@ -605,6 +618,12 @@ func (aruo *AuthRequestUpdateOne) SetNillableCodeChallengeMethod(s *string) *Aut
|
|||||||
return aruo
|
return aruo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHmacKey sets the "hmac_key" field.
|
||||||
|
func (aruo *AuthRequestUpdateOne) SetHmacKey(b []byte) *AuthRequestUpdateOne {
|
||||||
|
aruo.mutation.SetHmacKey(b)
|
||||||
|
return aruo
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the AuthRequestMutation object of the builder.
|
// Mutation returns the AuthRequestMutation object of the builder.
|
||||||
func (aruo *AuthRequestUpdateOne) Mutation() *AuthRequestMutation {
|
func (aruo *AuthRequestUpdateOne) Mutation() *AuthRequestMutation {
|
||||||
return aruo.mutation
|
return aruo.mutation
|
||||||
@ -863,6 +882,13 @@ func (aruo *AuthRequestUpdateOne) sqlSave(ctx context.Context) (_node *AuthReque
|
|||||||
Column: authrequest.FieldCodeChallengeMethod,
|
Column: authrequest.FieldCodeChallengeMethod,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if value, ok := aruo.mutation.HmacKey(); ok {
|
||||||
|
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||||
|
Type: field.TypeBytes,
|
||||||
|
Value: value,
|
||||||
|
Column: authrequest.FieldHmacKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
_node = &AuthRequest{config: aruo.config}
|
_node = &AuthRequest{config: aruo.config}
|
||||||
_spec.Assign = _node.assignValues
|
_spec.Assign = _node.assignValues
|
||||||
_spec.ScanValues = _node.scanValues
|
_spec.ScanValues = _node.scanValues
|
||||||
|
@ -55,6 +55,7 @@ var (
|
|||||||
{Name: "expiry", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime(3)", "postgres": "timestamptz", "sqlite3": "timestamp"}},
|
{Name: "expiry", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime(3)", "postgres": "timestamptz", "sqlite3": "timestamp"}},
|
||||||
{Name: "code_challenge", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
{Name: "code_challenge", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||||
{Name: "code_challenge_method", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
{Name: "code_challenge_method", Type: field.TypeString, Size: 2147483647, Default: "", SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||||
|
{Name: "hmac_key", Type: field.TypeBytes},
|
||||||
}
|
}
|
||||||
// AuthRequestsTable holds the schema information for the "auth_requests" table.
|
// AuthRequestsTable holds the schema information for the "auth_requests" table.
|
||||||
AuthRequestsTable = &schema.Table{
|
AuthRequestsTable = &schema.Table{
|
||||||
|
@ -1205,6 +1205,7 @@ type AuthRequestMutation struct {
|
|||||||
expiry *time.Time
|
expiry *time.Time
|
||||||
code_challenge *string
|
code_challenge *string
|
||||||
code_challenge_method *string
|
code_challenge_method *string
|
||||||
|
hmac_key *[]byte
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
done bool
|
done bool
|
||||||
oldValue func(context.Context) (*AuthRequest, error)
|
oldValue func(context.Context) (*AuthRequest, error)
|
||||||
@ -2051,6 +2052,42 @@ func (m *AuthRequestMutation) ResetCodeChallengeMethod() {
|
|||||||
m.code_challenge_method = nil
|
m.code_challenge_method = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHmacKey sets the "hmac_key" field.
|
||||||
|
func (m *AuthRequestMutation) SetHmacKey(b []byte) {
|
||||||
|
m.hmac_key = &b
|
||||||
|
}
|
||||||
|
|
||||||
|
// HmacKey returns the value of the "hmac_key" field in the mutation.
|
||||||
|
func (m *AuthRequestMutation) HmacKey() (r []byte, exists bool) {
|
||||||
|
v := m.hmac_key
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldHmacKey returns the old "hmac_key" field's value of the AuthRequest entity.
|
||||||
|
// If the AuthRequest object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *AuthRequestMutation) OldHmacKey(ctx context.Context) (v []byte, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldHmacKey is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldHmacKey requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldHmacKey: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.HmacKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetHmacKey resets all changes to the "hmac_key" field.
|
||||||
|
func (m *AuthRequestMutation) ResetHmacKey() {
|
||||||
|
m.hmac_key = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Where appends a list predicates to the AuthRequestMutation builder.
|
// Where appends a list predicates to the AuthRequestMutation builder.
|
||||||
func (m *AuthRequestMutation) Where(ps ...predicate.AuthRequest) {
|
func (m *AuthRequestMutation) Where(ps ...predicate.AuthRequest) {
|
||||||
m.predicates = append(m.predicates, ps...)
|
m.predicates = append(m.predicates, ps...)
|
||||||
@ -2070,7 +2107,7 @@ func (m *AuthRequestMutation) Type() string {
|
|||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *AuthRequestMutation) Fields() []string {
|
func (m *AuthRequestMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 19)
|
fields := make([]string, 0, 20)
|
||||||
if m.client_id != nil {
|
if m.client_id != nil {
|
||||||
fields = append(fields, authrequest.FieldClientID)
|
fields = append(fields, authrequest.FieldClientID)
|
||||||
}
|
}
|
||||||
@ -2128,6 +2165,9 @@ func (m *AuthRequestMutation) Fields() []string {
|
|||||||
if m.code_challenge_method != nil {
|
if m.code_challenge_method != nil {
|
||||||
fields = append(fields, authrequest.FieldCodeChallengeMethod)
|
fields = append(fields, authrequest.FieldCodeChallengeMethod)
|
||||||
}
|
}
|
||||||
|
if m.hmac_key != nil {
|
||||||
|
fields = append(fields, authrequest.FieldHmacKey)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2174,6 +2214,8 @@ func (m *AuthRequestMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.CodeChallenge()
|
return m.CodeChallenge()
|
||||||
case authrequest.FieldCodeChallengeMethod:
|
case authrequest.FieldCodeChallengeMethod:
|
||||||
return m.CodeChallengeMethod()
|
return m.CodeChallengeMethod()
|
||||||
|
case authrequest.FieldHmacKey:
|
||||||
|
return m.HmacKey()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@ -2221,6 +2263,8 @@ func (m *AuthRequestMutation) OldField(ctx context.Context, name string) (ent.Va
|
|||||||
return m.OldCodeChallenge(ctx)
|
return m.OldCodeChallenge(ctx)
|
||||||
case authrequest.FieldCodeChallengeMethod:
|
case authrequest.FieldCodeChallengeMethod:
|
||||||
return m.OldCodeChallengeMethod(ctx)
|
return m.OldCodeChallengeMethod(ctx)
|
||||||
|
case authrequest.FieldHmacKey:
|
||||||
|
return m.OldHmacKey(ctx)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unknown AuthRequest field %s", name)
|
return nil, fmt.Errorf("unknown AuthRequest field %s", name)
|
||||||
}
|
}
|
||||||
@ -2363,6 +2407,13 @@ func (m *AuthRequestMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetCodeChallengeMethod(v)
|
m.SetCodeChallengeMethod(v)
|
||||||
return nil
|
return nil
|
||||||
|
case authrequest.FieldHmacKey:
|
||||||
|
v, ok := value.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetHmacKey(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown AuthRequest field %s", name)
|
return fmt.Errorf("unknown AuthRequest field %s", name)
|
||||||
}
|
}
|
||||||
@ -2496,6 +2547,9 @@ func (m *AuthRequestMutation) ResetField(name string) error {
|
|||||||
case authrequest.FieldCodeChallengeMethod:
|
case authrequest.FieldCodeChallengeMethod:
|
||||||
m.ResetCodeChallengeMethod()
|
m.ResetCodeChallengeMethod()
|
||||||
return nil
|
return nil
|
||||||
|
case authrequest.FieldHmacKey:
|
||||||
|
m.ResetHmacKey()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown AuthRequest field %s", name)
|
return fmt.Errorf("unknown AuthRequest field %s", name)
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ create table auth_request
|
|||||||
expiry timestamp not null,
|
expiry timestamp not null,
|
||||||
claims_preferred_username text default '' not null,
|
claims_preferred_username text default '' not null,
|
||||||
code_challenge text default '' not null,
|
code_challenge text default '' not null,
|
||||||
code_challenge_method text default '' not null
|
code_challenge_method text default '' not null,
|
||||||
|
hmac_key blob
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -86,6 +87,7 @@ func (AuthRequest) Fields() []ent.Field {
|
|||||||
field.Text("code_challenge_method").
|
field.Text("code_challenge_method").
|
||||||
SchemaType(textSchema).
|
SchemaType(textSchema).
|
||||||
Default(""),
|
Default(""),
|
||||||
|
field.Bytes("hmac_key"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,8 @@ type AuthRequest struct {
|
|||||||
|
|
||||||
CodeChallenge string `json:"code_challenge,omitempty"`
|
CodeChallenge string `json:"code_challenge,omitempty"`
|
||||||
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
||||||
|
|
||||||
|
HMACKey []byte `json:"hmac_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
|
func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
|
||||||
@ -103,6 +105,7 @@ func fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
|
|||||||
ConnectorData: a.ConnectorData,
|
ConnectorData: a.ConnectorData,
|
||||||
CodeChallenge: a.PKCE.CodeChallenge,
|
CodeChallenge: a.PKCE.CodeChallenge,
|
||||||
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
|
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
|
||||||
|
HMACKey: a.HMACKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +128,7 @@ func toStorageAuthRequest(a AuthRequest) storage.AuthRequest {
|
|||||||
CodeChallenge: a.CodeChallenge,
|
CodeChallenge: a.CodeChallenge,
|
||||||
CodeChallengeMethod: a.CodeChallengeMethod,
|
CodeChallengeMethod: a.CodeChallengeMethod,
|
||||||
},
|
},
|
||||||
|
HMACKey: a.HMACKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -15,6 +16,7 @@ func NewCustomHealthCheckFunc(s Storage, now func() time.Time) func(context.Cont
|
|||||||
|
|
||||||
// Set a short expiry so if the delete fails this will be cleaned up quickly by garbage collection.
|
// Set a short expiry so if the delete fails this will be cleaned up quickly by garbage collection.
|
||||||
Expiry: now().Add(time.Minute),
|
Expiry: now().Add(time.Minute),
|
||||||
|
HMACKey: NewHMACKey(crypto.SHA256),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.CreateAuthRequest(a); err != nil {
|
if err := s.CreateAuthRequest(a); err != nil {
|
||||||
|
@ -356,6 +356,8 @@ type AuthRequest struct {
|
|||||||
|
|
||||||
CodeChallenge string `json:"code_challenge,omitempty"`
|
CodeChallenge string `json:"code_challenge,omitempty"`
|
||||||
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
CodeChallengeMethod string `json:"code_challenge_method,omitempty"`
|
||||||
|
|
||||||
|
HMACKey []byte `json:"hmac_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthRequestList is a list of AuthRequests.
|
// AuthRequestList is a list of AuthRequests.
|
||||||
@ -384,6 +386,7 @@ func toStorageAuthRequest(req AuthRequest) storage.AuthRequest {
|
|||||||
CodeChallenge: req.CodeChallenge,
|
CodeChallenge: req.CodeChallenge,
|
||||||
CodeChallengeMethod: req.CodeChallengeMethod,
|
CodeChallengeMethod: req.CodeChallengeMethod,
|
||||||
},
|
},
|
||||||
|
HMACKey: req.HMACKey,
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
@ -412,6 +415,7 @@ func (cli *client) fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
|
|||||||
Claims: fromStorageClaims(a.Claims),
|
Claims: fromStorageClaims(a.Claims),
|
||||||
CodeChallenge: a.PKCE.CodeChallenge,
|
CodeChallenge: a.PKCE.CodeChallenge,
|
||||||
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
|
CodeChallengeMethod: a.PKCE.CodeChallengeMethod,
|
||||||
|
HMACKey: a.HMACKey,
|
||||||
}
|
}
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
@ -131,10 +131,11 @@ func (c *conn) CreateAuthRequest(a storage.AuthRequest) error {
|
|||||||
claims_email, claims_email_verified, claims_groups,
|
claims_email, claims_email_verified, claims_groups,
|
||||||
connector_id, connector_data,
|
connector_id, connector_data,
|
||||||
expiry,
|
expiry,
|
||||||
code_challenge, code_challenge_method
|
code_challenge, code_challenge_method,
|
||||||
|
hmac_key
|
||||||
)
|
)
|
||||||
values (
|
values (
|
||||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21
|
||||||
);
|
);
|
||||||
`,
|
`,
|
||||||
a.ID, a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State,
|
a.ID, a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State,
|
||||||
@ -143,7 +144,7 @@ func (c *conn) CreateAuthRequest(a storage.AuthRequest) error {
|
|||||||
a.Claims.Email, a.Claims.EmailVerified, encoder(a.Claims.Groups),
|
a.Claims.Email, a.Claims.EmailVerified, encoder(a.Claims.Groups),
|
||||||
a.ConnectorID, a.ConnectorData,
|
a.ConnectorID, a.ConnectorData,
|
||||||
a.Expiry,
|
a.Expiry,
|
||||||
a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod,
|
a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod, a.HMACKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if c.alreadyExistsCheck(err) {
|
if c.alreadyExistsCheck(err) {
|
||||||
@ -175,8 +176,9 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest)
|
|||||||
claims_groups = $14,
|
claims_groups = $14,
|
||||||
connector_id = $15, connector_data = $16,
|
connector_id = $15, connector_data = $16,
|
||||||
expiry = $17,
|
expiry = $17,
|
||||||
code_challenge = $18, code_challenge_method = $19
|
code_challenge = $18, code_challenge_method = $19,
|
||||||
where id = $20;
|
hmac_key = $20
|
||||||
|
where id = $21;
|
||||||
`,
|
`,
|
||||||
a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State,
|
a.ClientID, encoder(a.ResponseTypes), encoder(a.Scopes), a.RedirectURI, a.Nonce, a.State,
|
||||||
a.ForceApprovalPrompt, a.LoggedIn,
|
a.ForceApprovalPrompt, a.LoggedIn,
|
||||||
@ -185,7 +187,7 @@ func (c *conn) UpdateAuthRequest(id string, updater func(a storage.AuthRequest)
|
|||||||
encoder(a.Claims.Groups),
|
encoder(a.Claims.Groups),
|
||||||
a.ConnectorID, a.ConnectorData,
|
a.ConnectorID, a.ConnectorData,
|
||||||
a.Expiry,
|
a.Expiry,
|
||||||
a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod,
|
a.PKCE.CodeChallenge, a.PKCE.CodeChallengeMethod, a.HMACKey,
|
||||||
r.ID,
|
r.ID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -207,7 +209,7 @@ func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) {
|
|||||||
claims_user_id, claims_username, claims_preferred_username,
|
claims_user_id, claims_username, claims_preferred_username,
|
||||||
claims_email, claims_email_verified, claims_groups,
|
claims_email, claims_email_verified, claims_groups,
|
||||||
connector_id, connector_data, expiry,
|
connector_id, connector_data, expiry,
|
||||||
code_challenge, code_challenge_method
|
code_challenge, code_challenge_method, hmac_key
|
||||||
from auth_request where id = $1;
|
from auth_request where id = $1;
|
||||||
`, id).Scan(
|
`, id).Scan(
|
||||||
&a.ID, &a.ClientID, decoder(&a.ResponseTypes), decoder(&a.Scopes), &a.RedirectURI, &a.Nonce, &a.State,
|
&a.ID, &a.ClientID, decoder(&a.ResponseTypes), decoder(&a.Scopes), &a.RedirectURI, &a.Nonce, &a.State,
|
||||||
@ -216,7 +218,7 @@ func getAuthRequest(q querier, id string) (a storage.AuthRequest, err error) {
|
|||||||
&a.Claims.Email, &a.Claims.EmailVerified,
|
&a.Claims.Email, &a.Claims.EmailVerified,
|
||||||
decoder(&a.Claims.Groups),
|
decoder(&a.Claims.Groups),
|
||||||
&a.ConnectorID, &a.ConnectorData, &a.Expiry,
|
&a.ConnectorID, &a.ConnectorData, &a.Expiry,
|
||||||
&a.PKCE.CodeChallenge, &a.PKCE.CodeChallengeMethod,
|
&a.PKCE.CodeChallenge, &a.PKCE.CodeChallengeMethod, &a.HMACKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -281,4 +281,11 @@ var migrations = []migration{
|
|||||||
add column obsolete_token text default '';`,
|
add column obsolete_token text default '';`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
stmts: []string{
|
||||||
|
`
|
||||||
|
alter table auth_request
|
||||||
|
add column hmac_key bytea;`,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"errors"
|
"errors"
|
||||||
@ -47,6 +48,11 @@ func newSecureID(len int) string {
|
|||||||
return string(buff[0]%26+'a') + strings.TrimRight(encoding.EncodeToString(buff[1:]), "=")
|
return string(buff[0]%26+'a') + strings.TrimRight(encoding.EncodeToString(buff[1:]), "=")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHMACKey returns a random key which can be used in the computation of an HMAC
|
||||||
|
func NewHMACKey(h crypto.Hash) []byte {
|
||||||
|
return []byte(newSecureID(h.Size()))
|
||||||
|
}
|
||||||
|
|
||||||
// GCResult returns the number of objects deleted by garbage collection.
|
// GCResult returns the number of objects deleted by garbage collection.
|
||||||
type GCResult struct {
|
type GCResult struct {
|
||||||
AuthRequests int64
|
AuthRequests int64
|
||||||
@ -223,6 +229,9 @@ type AuthRequest struct {
|
|||||||
|
|
||||||
// PKCE CodeChallenge and CodeChallengeMethod
|
// PKCE CodeChallenge and CodeChallengeMethod
|
||||||
PKCE PKCE
|
PKCE PKCE
|
||||||
|
|
||||||
|
// HMACKey is used when generating an AuthRequest-specific HMAC
|
||||||
|
HMACKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthCode represents a code which can be exchanged for an OAuth2 token response.
|
// AuthCode represents a code which can be exchanged for an OAuth2 token response.
|
||||||
|
Reference in New Issue
Block a user