snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
159
server/app/boot_auth.go
Normal file
159
server/app/boot_auth.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
authHandlers "github.com/cortezaproject/corteza/server/auth/handlers"
|
||||
"github.com/cortezaproject/corteza/server/auth/oauth2"
|
||||
"github.com/cortezaproject/corteza/server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza/server/pkg/id"
|
||||
"github.com/cortezaproject/corteza/server/pkg/options"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/lestrrat-go/jwx/jwa"
|
||||
"github.com/lestrrat-go/jwx/jwk"
|
||||
"github.com/lestrrat-go/jwx/jwt"
|
||||
"go.uber.org/zap"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (app *CortezaApp) initAuth(ctx context.Context) (err error) {
|
||||
log := app.Log.Named("auth")
|
||||
|
||||
if app.Opt.Auth.DefaultClient != "" {
|
||||
// default client will help streamline authorization with default clients
|
||||
app.DefaultAuthClient, err = store.LookupAuthClientByHandle(ctx, app.Store, app.Opt.Auth.DefaultClient)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load default client: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
app.oa2m = oauth2.NewManager(
|
||||
app.Opt.Auth,
|
||||
app.Log,
|
||||
oauth2.NewClientStore(app.Store, app.DefaultAuthClient),
|
||||
oauth2.NewTokenStore(app.Store),
|
||||
)
|
||||
|
||||
// set base path for links&routes in auth server
|
||||
authHandlers.BasePath = app.Opt.HTTPServer.BaseUrl
|
||||
|
||||
// set webapp base path in auth server
|
||||
// @todo refactor, consider passing this into the functions that need it instead of setting it globally
|
||||
authHandlers.WebappBasePath = app.Opt.HTTPServer.WebappBaseUrl
|
||||
|
||||
auth.DefaultSigner = auth.HmacSigner(app.Opt.Auth.Secret)
|
||||
|
||||
if auth.HttpTokenVerifier, err = auth.TokenVerifierMiddlewareWithSecretSigner(app.Opt.Auth.Secret); err != nil {
|
||||
return fmt.Errorf("could not set token verifier")
|
||||
}
|
||||
|
||||
// create token signature function from AUTH_ options
|
||||
// and pass it on to the token issuer
|
||||
alg, key, err := prepareSignatureFnParams(app.Opt.Auth)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not initialize token signer: %w", err)
|
||||
}
|
||||
|
||||
log.Info(
|
||||
"initializing JWT and authentication procedures",
|
||||
zap.Stringer("algoritm", alg),
|
||||
)
|
||||
|
||||
// construct token issuer with algorithm, secrets,
|
||||
auth.TokenIssuer, err = auth.NewTokenIssuer(
|
||||
auth.WithSigner(func(t jwt.Token) ([]byte, error) {
|
||||
return jwt.Sign(t, alg, key)
|
||||
}),
|
||||
|
||||
// @todo implement configurable issuer claim
|
||||
//auth.WithDefaultIssuer(app.Opt.Auth.TokenClaimIssuer),
|
||||
auth.WithDefaultExpiration(app.Opt.Auth.AccessTokenLifetime),
|
||||
auth.WithDefaultClientID(app.DefaultAuthClient.ID),
|
||||
auth.WithLookup(func(ctx context.Context, accessToken string) (err error) {
|
||||
_, err = store.LookupAuthOa2tokenByAccess(ctx, app.Store, accessToken)
|
||||
return err
|
||||
}),
|
||||
auth.WithStore(func(ctx context.Context, req auth.TokenRequest) error {
|
||||
var (
|
||||
eti = auth.GetExtraReqInfoFromContext(ctx)
|
||||
createdAt = req.IssuedAt
|
||||
|
||||
oa2t = &types.AuthOa2token{
|
||||
ID: id.Next(),
|
||||
Access: req.AccessToken,
|
||||
Refresh: req.RefreshToken,
|
||||
CreatedAt: createdAt,
|
||||
RemoteAddr: eti.RemoteAddr,
|
||||
UserAgent: eti.UserAgent,
|
||||
ClientID: req.ClientID,
|
||||
UserID: req.UserID,
|
||||
ExpiresAt: createdAt.Add(req.Expiration),
|
||||
}
|
||||
)
|
||||
|
||||
return store.CreateAuthOa2token(ctx, app.Store, oa2t)
|
||||
}),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not initialize token issuer: %w", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// helper function that loads and/or parses private keys and initializes JWT signer function
|
||||
// from the given arguments
|
||||
func prepareSignatureFnParams(opt options.AuthOpt) (alg jwa.SignatureAlgorithm, key any, err error) {
|
||||
alg = jwa.SignatureAlgorithm(opt.JwtAlgorithm)
|
||||
|
||||
switch alg {
|
||||
case jwa.HS256, jwa.HS384, jwa.HS512:
|
||||
// expecting secret to be set
|
||||
if len(opt.Secret) == 0 {
|
||||
return alg, nil, fmt.Errorf("token secret missing")
|
||||
}
|
||||
|
||||
key = []byte(opt.Secret)
|
||||
case
|
||||
jwa.PS256, jwa.PS384, jwa.PS512,
|
||||
jwa.RS256, jwa.RS384, jwa.RS512:
|
||||
if len(opt.JwtKey) == 0 {
|
||||
return alg, nil, fmt.Errorf("token key missing")
|
||||
}
|
||||
|
||||
// if given key dos not begins with "-----BEGIN"
|
||||
// assume it's path to a file and load contents of that file
|
||||
if !strings.HasPrefix(opt.JwtKey, "-----BEGIN") {
|
||||
var (
|
||||
keyFile = opt.JwtKey
|
||||
b []byte
|
||||
)
|
||||
if b, err = ioutil.ReadFile(keyFile); err != nil {
|
||||
return alg, nil, fmt.Errorf("could not read key file: %w", err)
|
||||
}
|
||||
|
||||
// overwrite th input and load
|
||||
opt.JwtKey = string(b)
|
||||
|
||||
// recheck contents of the key
|
||||
if !strings.HasPrefix(opt.JwtKey, "-----BEGIN") {
|
||||
return alg, nil, fmt.Errorf("file %q does not contain a valid private key", keyFile)
|
||||
}
|
||||
}
|
||||
|
||||
// generates pem.Private from the kInput string
|
||||
key, err = jwk.ParseKey([]byte(opt.JwtKey), jwk.WithPEM(true))
|
||||
case "":
|
||||
// should be caught by options init procedure and set to default,
|
||||
// but you never know...
|
||||
err = fmt.Errorf("token signature algorithm empty or missing")
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("token signature algorithm %q not supported", alg)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user