fix(storage): don't check exp against time using sql (#2676)

This is already checked by JWT validation. There is no need and it's leading to timezone issues.

Fixes #2672
pull/2669/head^2
James Elliott 2021-12-04 15:34:20 +11:00 committed by GitHub
parent 09fbffa3ac
commit 5a223b5a56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 15 deletions

View File

@ -51,6 +51,8 @@ func (ip *IP) Scan(src interface{}) (err error) {
switch v := src.(type) { switch v := src.(type) {
case string: case string:
value = v value = v
case []byte:
value = string(v)
default: default:
return fmt.Errorf("invalid type %T for IP %v", src, src) return fmt.Errorf("invalid type %T for IP %v", src, src)
} }
@ -86,6 +88,8 @@ func (ip *NullIP) Scan(src interface{}) (err error) {
switch v := src.(type) { switch v := src.(type) {
case string: case string:
value = v value = v
case []byte:
value = string(v)
default: default:
return fmt.Errorf("invalid type %T for NullIP %v", src, src) return fmt.Errorf("invalid type %T for NullIP %v", src, src)
} }

View File

@ -33,9 +33,9 @@ func NewSQLProvider(config *schema.Configuration, name, driverName, dataSourceNa
sqlInsertAuthenticationAttempt: fmt.Sprintf(queryFmtInsertAuthenticationLogEntry, tableAuthenticationLogs), sqlInsertAuthenticationAttempt: fmt.Sprintf(queryFmtInsertAuthenticationLogEntry, tableAuthenticationLogs),
sqlSelectAuthenticationAttemptsByUsername: fmt.Sprintf(queryFmtSelect1FAAuthenticationLogEntryByUsername, tableAuthenticationLogs), sqlSelectAuthenticationAttemptsByUsername: fmt.Sprintf(queryFmtSelect1FAAuthenticationLogEntryByUsername, tableAuthenticationLogs),
sqlInsertIdentityVerification: fmt.Sprintf(queryFmtInsertIdentityVerification, tableIdentityVerification), sqlInsertIdentityVerification: fmt.Sprintf(queryFmtInsertIdentityVerification, tableIdentityVerification),
sqlConsumeIdentityVerification: fmt.Sprintf(queryFmtConsumeIdentityVerification, tableIdentityVerification), sqlConsumeIdentityVerification: fmt.Sprintf(queryFmtConsumeIdentityVerification, tableIdentityVerification),
sqlSelectExistsIdentityVerification: fmt.Sprintf(queryFmtSelectExistsIdentityVerification, tableIdentityVerification), sqlSelectIdentityVerification: fmt.Sprintf(queryFmtSelectIdentityVerification, tableIdentityVerification),
sqlUpsertTOTPConfig: fmt.Sprintf(queryFmtUpsertTOTPConfiguration, tableTOTPConfigurations), sqlUpsertTOTPConfig: fmt.Sprintf(queryFmtUpsertTOTPConfiguration, tableTOTPConfigurations),
sqlDeleteTOTPConfig: fmt.Sprintf(queryFmtDeleteTOTPConfiguration, tableTOTPConfigurations), sqlDeleteTOTPConfig: fmt.Sprintf(queryFmtDeleteTOTPConfiguration, tableTOTPConfigurations),
@ -90,9 +90,9 @@ type SQLProvider struct {
sqlSelectAuthenticationAttemptsByUsername string sqlSelectAuthenticationAttemptsByUsername string
// Table: identity_verification. // Table: identity_verification.
sqlInsertIdentityVerification string sqlInsertIdentityVerification string
sqlConsumeIdentityVerification string sqlConsumeIdentityVerification string
sqlSelectExistsIdentityVerification string sqlSelectIdentityVerification string
// Table: totp_configurations. // Table: totp_configurations.
sqlUpsertTOTPConfig string sqlUpsertTOTPConfig string
@ -245,11 +245,21 @@ func (p *SQLProvider) ConsumeIdentityVerification(ctx context.Context, jti strin
// FindIdentityVerification checks if an identity verification record is in the database and active. // FindIdentityVerification checks if an identity verification record is in the database and active.
func (p *SQLProvider) FindIdentityVerification(ctx context.Context, jti string) (found bool, err error) { func (p *SQLProvider) FindIdentityVerification(ctx context.Context, jti string) (found bool, err error) {
if err = p.db.GetContext(ctx, &found, p.sqlSelectExistsIdentityVerification, jti); err != nil { verification := models.IdentityVerification{}
if err = p.db.GetContext(ctx, &verification, p.sqlSelectIdentityVerification, jti); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
return false, fmt.Errorf("error selecting identity verification exists: %w", err) return false, fmt.Errorf("error selecting identity verification exists: %w", err)
} }
return found, nil switch {
case verification.Consumed != nil, verification.ExpiresAt.Before(time.Now()):
return false, nil
default:
return true, nil
}
} }
// SaveTOTPConfiguration save a TOTP configuration of a given user in the database. // SaveTOTPConfiguration save a TOTP configuration of a given user in the database.

View File

@ -36,7 +36,7 @@ func NewPostgreSQLProvider(config *schema.Configuration) (provider *PostgreSQLPr
provider.sqlFmtRenameTable = provider.db.Rebind(provider.sqlFmtRenameTable) provider.sqlFmtRenameTable = provider.db.Rebind(provider.sqlFmtRenameTable)
provider.sqlSelectPreferred2FAMethod = provider.db.Rebind(provider.sqlSelectPreferred2FAMethod) provider.sqlSelectPreferred2FAMethod = provider.db.Rebind(provider.sqlSelectPreferred2FAMethod)
provider.sqlSelectUserInfo = provider.db.Rebind(provider.sqlSelectUserInfo) provider.sqlSelectUserInfo = provider.db.Rebind(provider.sqlSelectUserInfo)
provider.sqlSelectExistsIdentityVerification = provider.db.Rebind(provider.sqlSelectExistsIdentityVerification) provider.sqlSelectIdentityVerification = provider.db.Rebind(provider.sqlSelectIdentityVerification)
provider.sqlInsertIdentityVerification = provider.db.Rebind(provider.sqlInsertIdentityVerification) provider.sqlInsertIdentityVerification = provider.db.Rebind(provider.sqlInsertIdentityVerification)
provider.sqlConsumeIdentityVerification = provider.db.Rebind(provider.sqlConsumeIdentityVerification) provider.sqlConsumeIdentityVerification = provider.db.Rebind(provider.sqlConsumeIdentityVerification)
provider.sqlSelectTOTPConfig = provider.db.Rebind(provider.sqlSelectTOTPConfig) provider.sqlSelectTOTPConfig = provider.db.Rebind(provider.sqlSelectTOTPConfig)

View File

@ -56,12 +56,10 @@ const (
) )
const ( const (
queryFmtSelectExistsIdentityVerification = ` queryFmtSelectIdentityVerification = `
SELECT EXISTS ( SELECT id, jti, iat, issued_ip, exp, username, action, consumed, consumed_ip
SELECT id FROM %s
FROM %s WHERE jti = ?;`
WHERE jti = ? AND exp > CURRENT_TIMESTAMP AND consumed IS NULL
);`
queryFmtInsertIdentityVerification = ` queryFmtInsertIdentityVerification = `
INSERT INTO %s (jti, iat, issued_ip, exp, username, action) INSERT INTO %s (jti, iat, issued_ip, exp, username, action)