2021-11-23 09:45:38 +00:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
_ "github.com/jackc/pgx/v4/stdlib" // Load the PostgreSQL Driver used in the connection string.
|
|
|
|
|
|
|
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
|
|
|
)
|
|
|
|
|
|
|
|
// PostgreSQLProvider is a PostgreSQL provider.
|
|
|
|
type PostgreSQLProvider struct {
|
|
|
|
SQLProvider
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewPostgreSQLProvider a PostgreSQL provider.
|
2021-12-01 12:11:29 +00:00
|
|
|
func NewPostgreSQLProvider(config *schema.Configuration) (provider *PostgreSQLProvider) {
|
2021-11-23 09:45:38 +00:00
|
|
|
provider = &PostgreSQLProvider{
|
2021-12-01 12:11:29 +00:00
|
|
|
SQLProvider: NewSQLProvider(config, providerPostgres, "pgx", dataSourceNamePostgreSQL(*config.Storage.PostgreSQL)),
|
2021-11-23 09:45:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// All providers have differing SELECT existing table statements.
|
|
|
|
provider.sqlSelectExistingTables = queryPostgreSelectExistingTables
|
|
|
|
|
|
|
|
// Specific alterations to this provider.
|
|
|
|
// PostgreSQL doesn't have a UPSERT statement but has an ON CONFLICT operation instead.
|
2022-04-07 05:33:53 +00:00
|
|
|
provider.sqlUpsertWebauthnDevice = fmt.Sprintf(queryFmtUpsertWebauthnDevicePostgreSQL, tableWebauthnDevices)
|
|
|
|
provider.sqlUpsertDuoDevice = fmt.Sprintf(queryFmtUpsertDuoDevicePostgreSQL, tableDuoDevices)
|
|
|
|
provider.sqlUpsertTOTPConfig = fmt.Sprintf(queryFmtUpsertTOTPConfigurationPostgreSQL, tableTOTPConfigurations)
|
|
|
|
provider.sqlUpsertPreferred2FAMethod = fmt.Sprintf(queryFmtUpsertPreferred2FAMethodPostgreSQL, tableUserPreferences)
|
|
|
|
provider.sqlUpsertEncryptionValue = fmt.Sprintf(queryFmtUpsertEncryptionValuePostgreSQL, tableEncryption)
|
|
|
|
provider.sqlUpsertOAuth2BlacklistedJTI = fmt.Sprintf(queryFmtUpsertOAuth2BlacklistedJTIPostgreSQL, tableOAuth2BlacklistedJTI)
|
2022-10-20 02:16:36 +00:00
|
|
|
provider.sqlInsertOAuth2ConsentPreConfiguration = fmt.Sprintf(queryFmtInsertOAuth2ConsentPreConfigurationPostgreSQL, tableOAuth2ConsentPreConfiguration)
|
2021-11-23 09:45:38 +00:00
|
|
|
|
|
|
|
// PostgreSQL requires rebinding of any query that contains a '?' placeholder to use the '$#' notation placeholders.
|
|
|
|
provider.sqlFmtRenameTable = provider.db.Rebind(provider.sqlFmtRenameTable)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlSelectPreferred2FAMethod = provider.db.Rebind(provider.sqlSelectPreferred2FAMethod)
|
|
|
|
provider.sqlSelectUserInfo = provider.db.Rebind(provider.sqlSelectUserInfo)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
|
|
|
provider.sqlInsertUserOpaqueIdentifier = provider.db.Rebind(provider.sqlInsertUserOpaqueIdentifier)
|
|
|
|
provider.sqlSelectUserOpaqueIdentifier = provider.db.Rebind(provider.sqlSelectUserOpaqueIdentifier)
|
|
|
|
provider.sqlSelectUserOpaqueIdentifierBySignature = provider.db.Rebind(provider.sqlSelectUserOpaqueIdentifierBySignature)
|
|
|
|
|
2021-12-04 04:34:20 +00:00
|
|
|
provider.sqlSelectIdentityVerification = provider.db.Rebind(provider.sqlSelectIdentityVerification)
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlInsertIdentityVerification = provider.db.Rebind(provider.sqlInsertIdentityVerification)
|
2021-12-03 00:04:11 +00:00
|
|
|
provider.sqlConsumeIdentityVerification = provider.db.Rebind(provider.sqlConsumeIdentityVerification)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlSelectTOTPConfig = provider.db.Rebind(provider.sqlSelectTOTPConfig)
|
2022-03-03 11:20:43 +00:00
|
|
|
provider.sqlUpdateTOTPConfigRecordSignIn = provider.db.Rebind(provider.sqlUpdateTOTPConfigRecordSignIn)
|
|
|
|
provider.sqlUpdateTOTPConfigRecordSignInByUsername = provider.db.Rebind(provider.sqlUpdateTOTPConfigRecordSignInByUsername)
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlDeleteTOTPConfig = provider.db.Rebind(provider.sqlDeleteTOTPConfig)
|
2021-11-25 01:56:58 +00:00
|
|
|
provider.sqlSelectTOTPConfigs = provider.db.Rebind(provider.sqlSelectTOTPConfigs)
|
|
|
|
provider.sqlUpdateTOTPConfigSecret = provider.db.Rebind(provider.sqlUpdateTOTPConfigSecret)
|
|
|
|
provider.sqlUpdateTOTPConfigSecretByUsername = provider.db.Rebind(provider.sqlUpdateTOTPConfigSecretByUsername)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2022-03-03 11:20:43 +00:00
|
|
|
provider.sqlSelectWebauthnDevices = provider.db.Rebind(provider.sqlSelectWebauthnDevices)
|
|
|
|
provider.sqlSelectWebauthnDevicesByUsername = provider.db.Rebind(provider.sqlSelectWebauthnDevicesByUsername)
|
|
|
|
provider.sqlUpdateWebauthnDevicePublicKey = provider.db.Rebind(provider.sqlUpdateWebauthnDevicePublicKey)
|
|
|
|
provider.sqlUpdateWebauthnDevicePublicKeyByUsername = provider.db.Rebind(provider.sqlUpdateWebauthnDevicePublicKeyByUsername)
|
|
|
|
provider.sqlUpdateWebauthnDeviceRecordSignIn = provider.db.Rebind(provider.sqlUpdateWebauthnDeviceRecordSignIn)
|
|
|
|
provider.sqlUpdateWebauthnDeviceRecordSignInByUsername = provider.db.Rebind(provider.sqlUpdateWebauthnDeviceRecordSignInByUsername)
|
2022-10-19 07:17:55 +00:00
|
|
|
provider.sqlDeleteWebauthnDevice = provider.db.Rebind(provider.sqlDeleteWebauthnDevice)
|
|
|
|
provider.sqlDeleteWebauthnDeviceByUsername = provider.db.Rebind(provider.sqlDeleteWebauthnDeviceByUsername)
|
|
|
|
provider.sqlDeleteWebauthnDeviceByUsernameAndDescription = provider.db.Rebind(provider.sqlDeleteWebauthnDeviceByUsernameAndDescription)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-12-02 06:06:04 +00:00
|
|
|
provider.sqlSelectDuoDevice = provider.db.Rebind(provider.sqlSelectDuoDevice)
|
|
|
|
provider.sqlDeleteDuoDevice = provider.db.Rebind(provider.sqlDeleteDuoDevice)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlInsertAuthenticationAttempt = provider.db.Rebind(provider.sqlInsertAuthenticationAttempt)
|
|
|
|
provider.sqlSelectAuthenticationAttemptsByUsername = provider.db.Rebind(provider.sqlSelectAuthenticationAttemptsByUsername)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
provider.sqlInsertMigration = provider.db.Rebind(provider.sqlInsertMigration)
|
2021-12-02 06:06:04 +00:00
|
|
|
provider.sqlSelectMigrations = provider.db.Rebind(provider.sqlSelectMigrations)
|
|
|
|
provider.sqlSelectLatestMigration = provider.db.Rebind(provider.sqlSelectLatestMigration)
|
2022-04-07 05:33:53 +00:00
|
|
|
|
2021-11-25 01:56:58 +00:00
|
|
|
provider.sqlSelectEncryptionValue = provider.db.Rebind(provider.sqlSelectEncryptionValue)
|
2021-11-23 09:45:38 +00:00
|
|
|
|
2022-10-20 02:16:36 +00:00
|
|
|
provider.sqlSelectOAuth2ConsentPreConfigurations = provider.db.Rebind(provider.sqlSelectOAuth2ConsentPreConfigurations)
|
|
|
|
|
2022-04-07 05:33:53 +00:00
|
|
|
provider.sqlInsertOAuth2ConsentSession = provider.db.Rebind(provider.sqlInsertOAuth2ConsentSession)
|
2022-04-25 00:31:05 +00:00
|
|
|
provider.sqlUpdateOAuth2ConsentSessionSubject = provider.db.Rebind(provider.sqlUpdateOAuth2ConsentSessionSubject)
|
2022-04-07 05:33:53 +00:00
|
|
|
provider.sqlUpdateOAuth2ConsentSessionResponse = provider.db.Rebind(provider.sqlUpdateOAuth2ConsentSessionResponse)
|
|
|
|
provider.sqlUpdateOAuth2ConsentSessionGranted = provider.db.Rebind(provider.sqlUpdateOAuth2ConsentSessionGranted)
|
|
|
|
provider.sqlSelectOAuth2ConsentSessionByChallengeID = provider.db.Rebind(provider.sqlSelectOAuth2ConsentSessionByChallengeID)
|
|
|
|
|
|
|
|
provider.sqlInsertOAuth2AuthorizeCodeSession = provider.db.Rebind(provider.sqlInsertOAuth2AuthorizeCodeSession)
|
|
|
|
provider.sqlRevokeOAuth2AuthorizeCodeSession = provider.db.Rebind(provider.sqlRevokeOAuth2AuthorizeCodeSession)
|
|
|
|
provider.sqlRevokeOAuth2AuthorizeCodeSessionByRequestID = provider.db.Rebind(provider.sqlRevokeOAuth2AuthorizeCodeSessionByRequestID)
|
|
|
|
provider.sqlDeactivateOAuth2AuthorizeCodeSession = provider.db.Rebind(provider.sqlDeactivateOAuth2AuthorizeCodeSession)
|
|
|
|
provider.sqlDeactivateOAuth2AuthorizeCodeSessionByRequestID = provider.db.Rebind(provider.sqlDeactivateOAuth2AuthorizeCodeSessionByRequestID)
|
|
|
|
provider.sqlSelectOAuth2AuthorizeCodeSession = provider.db.Rebind(provider.sqlSelectOAuth2AuthorizeCodeSession)
|
|
|
|
|
|
|
|
provider.sqlInsertOAuth2AccessTokenSession = provider.db.Rebind(provider.sqlInsertOAuth2AccessTokenSession)
|
|
|
|
provider.sqlRevokeOAuth2AccessTokenSession = provider.db.Rebind(provider.sqlRevokeOAuth2AccessTokenSession)
|
|
|
|
provider.sqlRevokeOAuth2AccessTokenSessionByRequestID = provider.db.Rebind(provider.sqlRevokeOAuth2AccessTokenSessionByRequestID)
|
|
|
|
provider.sqlDeactivateOAuth2AccessTokenSession = provider.db.Rebind(provider.sqlDeactivateOAuth2AccessTokenSession)
|
|
|
|
provider.sqlDeactivateOAuth2AccessTokenSessionByRequestID = provider.db.Rebind(provider.sqlDeactivateOAuth2AccessTokenSessionByRequestID)
|
|
|
|
provider.sqlSelectOAuth2AccessTokenSession = provider.db.Rebind(provider.sqlSelectOAuth2AccessTokenSession)
|
|
|
|
|
|
|
|
provider.sqlInsertOAuth2RefreshTokenSession = provider.db.Rebind(provider.sqlInsertOAuth2RefreshTokenSession)
|
|
|
|
provider.sqlRevokeOAuth2RefreshTokenSession = provider.db.Rebind(provider.sqlRevokeOAuth2RefreshTokenSession)
|
|
|
|
provider.sqlRevokeOAuth2RefreshTokenSessionByRequestID = provider.db.Rebind(provider.sqlRevokeOAuth2RefreshTokenSessionByRequestID)
|
|
|
|
provider.sqlDeactivateOAuth2RefreshTokenSession = provider.db.Rebind(provider.sqlDeactivateOAuth2RefreshTokenSession)
|
|
|
|
provider.sqlDeactivateOAuth2RefreshTokenSessionByRequestID = provider.db.Rebind(provider.sqlDeactivateOAuth2RefreshTokenSessionByRequestID)
|
|
|
|
provider.sqlSelectOAuth2RefreshTokenSession = provider.db.Rebind(provider.sqlSelectOAuth2RefreshTokenSession)
|
|
|
|
|
|
|
|
provider.sqlInsertOAuth2PKCERequestSession = provider.db.Rebind(provider.sqlInsertOAuth2PKCERequestSession)
|
|
|
|
provider.sqlRevokeOAuth2PKCERequestSession = provider.db.Rebind(provider.sqlRevokeOAuth2PKCERequestSession)
|
|
|
|
provider.sqlRevokeOAuth2PKCERequestSessionByRequestID = provider.db.Rebind(provider.sqlRevokeOAuth2PKCERequestSessionByRequestID)
|
|
|
|
provider.sqlDeactivateOAuth2PKCERequestSession = provider.db.Rebind(provider.sqlDeactivateOAuth2PKCERequestSession)
|
|
|
|
provider.sqlDeactivateOAuth2PKCERequestSessionByRequestID = provider.db.Rebind(provider.sqlDeactivateOAuth2PKCERequestSessionByRequestID)
|
|
|
|
provider.sqlSelectOAuth2PKCERequestSession = provider.db.Rebind(provider.sqlSelectOAuth2PKCERequestSession)
|
|
|
|
|
|
|
|
provider.sqlInsertOAuth2OpenIDConnectSession = provider.db.Rebind(provider.sqlInsertOAuth2OpenIDConnectSession)
|
|
|
|
provider.sqlRevokeOAuth2OpenIDConnectSession = provider.db.Rebind(provider.sqlRevokeOAuth2OpenIDConnectSession)
|
|
|
|
provider.sqlRevokeOAuth2OpenIDConnectSessionByRequestID = provider.db.Rebind(provider.sqlRevokeOAuth2OpenIDConnectSessionByRequestID)
|
|
|
|
provider.sqlDeactivateOAuth2OpenIDConnectSession = provider.db.Rebind(provider.sqlDeactivateOAuth2OpenIDConnectSession)
|
|
|
|
provider.sqlDeactivateOAuth2OpenIDConnectSessionByRequestID = provider.db.Rebind(provider.sqlDeactivateOAuth2OpenIDConnectSessionByRequestID)
|
|
|
|
provider.sqlSelectOAuth2OpenIDConnectSession = provider.db.Rebind(provider.sqlSelectOAuth2OpenIDConnectSession)
|
|
|
|
|
|
|
|
provider.sqlSelectOAuth2BlacklistedJTI = provider.db.Rebind(provider.sqlSelectOAuth2BlacklistedJTI)
|
|
|
|
|
2021-12-03 06:29:55 +00:00
|
|
|
provider.schema = config.Storage.PostgreSQL.Schema
|
|
|
|
|
2021-11-23 09:45:38 +00:00
|
|
|
return provider
|
|
|
|
}
|
|
|
|
|
|
|
|
func dataSourceNamePostgreSQL(config schema.PostgreSQLStorageConfiguration) (dataSourceName string) {
|
|
|
|
args := []string{
|
2021-12-02 05:36:03 +00:00
|
|
|
fmt.Sprintf("host=%s", config.Host),
|
2021-11-23 09:45:38 +00:00
|
|
|
fmt.Sprintf("user='%s'", config.Username),
|
|
|
|
fmt.Sprintf("password='%s'", config.Password),
|
2021-12-02 05:36:03 +00:00
|
|
|
fmt.Sprintf("dbname=%s", config.Database),
|
2021-12-03 06:29:55 +00:00
|
|
|
fmt.Sprintf("search_path=%s", config.Schema),
|
|
|
|
fmt.Sprintf("sslmode=%s", config.SSL.Mode),
|
2021-11-23 09:45:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if config.Port > 0 {
|
|
|
|
args = append(args, fmt.Sprintf("port=%d", config.Port))
|
|
|
|
}
|
|
|
|
|
2021-12-02 05:36:03 +00:00
|
|
|
if config.SSL.RootCertificate != "" {
|
|
|
|
args = append(args, fmt.Sprintf("sslrootcert=%s", config.SSL.RootCertificate))
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.SSL.Certificate != "" {
|
|
|
|
args = append(args, fmt.Sprintf("sslcert=%s", config.SSL.Certificate))
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.SSL.Key != "" {
|
|
|
|
args = append(args, fmt.Sprintf("sslkey=%s", config.SSL.Key))
|
2021-11-23 09:45:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
args = append(args, fmt.Sprintf("connect_timeout=%d", int32(config.Timeout/time.Second)))
|
|
|
|
|
|
|
|
return strings.Join(args, " ")
|
|
|
|
}
|