@@ -25,6 +25,7 @@ type (
|
||||
Password passwordConfig `json:"password"`
|
||||
DisableSignup bool `json:"disable-signup"`
|
||||
InvitationConfirmationTokenValidity int `json:"invitation-confirmation-token-validity"`
|
||||
SAML samlConfig `json:"saml"`
|
||||
}
|
||||
|
||||
trustAuthConfig struct {
|
||||
|
||||
@@ -118,6 +118,10 @@ func New() *Implm {
|
||||
},
|
||||
DisableSignup: false,
|
||||
InvitationConfirmationTokenValidity: 3600,
|
||||
SAML: samlConfig{
|
||||
SessionDuration: 604800,
|
||||
CleanupIntervalSeconds: 86400,
|
||||
},
|
||||
},
|
||||
TrustAuth: trustAuthConfig{
|
||||
CookieName: "TCT",
|
||||
@@ -268,9 +272,11 @@ func (impl *Implm) Run(
|
||||
authService, err := auth.NewService(
|
||||
ctx,
|
||||
pgClient,
|
||||
impl.cfg.EncryptionKey,
|
||||
hp,
|
||||
impl.cfg.Auth.Cookie.Secret,
|
||||
impl.cfg.Hostname,
|
||||
fmt.Sprintf("https://%s", impl.cfg.Hostname),
|
||||
impl.cfg.Auth.DisableSignup,
|
||||
time.Duration(impl.cfg.Auth.InvitationConfirmationTokenValidity)*time.Second,
|
||||
)
|
||||
@@ -291,6 +297,21 @@ func (impl *Implm) Run(
|
||||
|
||||
fileManagerService := filemanager.NewService(s3Client)
|
||||
|
||||
samlService, err := auth.NewSAMLService(
|
||||
pgClient,
|
||||
impl.cfg.EncryptionKey,
|
||||
fmt.Sprintf("https://%s", impl.cfg.Hostname),
|
||||
impl.cfg.Auth.SAML.SessionDurationTime(),
|
||||
impl.cfg.Auth.Cookie.Name,
|
||||
impl.cfg.Auth.Cookie.Secret,
|
||||
impl.cfg.Auth.SAML.Certificate,
|
||||
impl.cfg.Auth.SAML.PrivateKey,
|
||||
l.Named("saml"),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create SAML service: %w", err)
|
||||
}
|
||||
|
||||
var accountKey crypto.Signer
|
||||
if impl.cfg.CustomDomains.ACME.AccountKey != "" {
|
||||
accountKey, err = pem.DecodePrivateKey([]byte(impl.cfg.CustomDomains.ACME.AccountKey))
|
||||
@@ -368,10 +389,13 @@ func (impl *Implm) Run(
|
||||
Auth: authService,
|
||||
Authz: authzService,
|
||||
Trust: trustService,
|
||||
SAML: samlService,
|
||||
ConnectorRegistry: defaultConnectorRegistry,
|
||||
Agent: agent,
|
||||
SafeRedirect: &saferedirect.SafeRedirect{AllowedHost: impl.cfg.Hostname},
|
||||
CustomDomainCname: impl.cfg.CustomDomains.CnameTarget,
|
||||
FileManager: fileManagerService,
|
||||
PGClient: pgClient,
|
||||
Logger: l.Named("http.server"),
|
||||
ConsoleAuth: api.ConsoleAuthConfig{
|
||||
CookieName: impl.cfg.Auth.Cookie.Name,
|
||||
@@ -445,6 +469,20 @@ func (impl *Implm) Run(
|
||||
},
|
||||
)
|
||||
|
||||
samlCleanerCtx, stopSAMLCleaner := context.WithCancel(context.Background())
|
||||
samlCleaner := auth.NewCleaner(
|
||||
pgClient,
|
||||
impl.cfg.Auth.SAML.CleanupInterval(),
|
||||
l.Named("saml-cleaner"),
|
||||
)
|
||||
wg.Go(
|
||||
func() {
|
||||
if err := samlCleaner.Run(samlCleanerCtx); err != nil {
|
||||
cancel(fmt.Errorf("saml cleaner crashed: %w", err))
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
trustCenterServerCtx, stopTrustCenterServer := context.WithCancel(context.Background())
|
||||
defer stopTrustCenterServer()
|
||||
wg.Go(
|
||||
@@ -460,6 +498,7 @@ func (impl *Implm) Run(
|
||||
stopMailer()
|
||||
stopSlackSender()
|
||||
stopExportJobExporter()
|
||||
stopSAMLCleaner()
|
||||
stopApiServer()
|
||||
stopTrustCenterServer()
|
||||
|
||||
|
||||
40
pkg/probod/saml_config.go
Normal file
40
pkg/probod/saml_config.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package probod
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type samlConfig struct {
|
||||
SessionDuration int `json:"session-duration"`
|
||||
CleanupIntervalSeconds int `json:"cleanup-interval-seconds"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKey string `json:"private-key"`
|
||||
}
|
||||
|
||||
func (c samlConfig) SessionDurationTime() time.Duration {
|
||||
if c.SessionDuration == 0 {
|
||||
return 7 * 24 * time.Hour
|
||||
}
|
||||
return time.Duration(c.SessionDuration) * time.Second
|
||||
}
|
||||
|
||||
func (c samlConfig) CleanupInterval() time.Duration {
|
||||
if c.CleanupIntervalSeconds == 0 {
|
||||
return 0
|
||||
}
|
||||
return time.Duration(c.CleanupIntervalSeconds) * time.Second
|
||||
}
|
||||
Reference in New Issue
Block a user