mirror of https://github.com/authelia/authelia.git
69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
package model
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/authelia/authelia/v4/internal/random"
|
|
)
|
|
|
|
const (
|
|
// OTCIntentUserSessionElevation is the intent value for a one-time code indicating it's used for user session
|
|
// elevation.
|
|
OTCIntentUserSessionElevation = "use"
|
|
)
|
|
|
|
// NewOneTimeCode returns a new OneTimeCode.
|
|
func NewOneTimeCode(ctx Context, username string, characters int, duration time.Duration) (otp *OneTimeCode, err error) {
|
|
var (
|
|
publicID uuid.UUID
|
|
code []byte
|
|
)
|
|
|
|
src := ctx.GetRandom()
|
|
|
|
if publicID, err = uuid.NewRandomFromReader(src); err != nil {
|
|
return nil, fmt.Errorf("failed to generate public id: %w", err)
|
|
}
|
|
|
|
if code, err = src.BytesCustomErr(characters, []byte(random.CharSetUnambiguousUpper)); err != nil {
|
|
return nil, fmt.Errorf("failed to generate random bytes: %w", err)
|
|
}
|
|
|
|
return &OneTimeCode{
|
|
PublicID: publicID,
|
|
IssuedAt: ctx.GetClock().Now(),
|
|
IssuedIP: NewIP(ctx.RemoteIP()),
|
|
ExpiresAt: ctx.GetClock().Now().Add(duration),
|
|
Username: username,
|
|
Intent: OTCIntentUserSessionElevation,
|
|
Code: code,
|
|
}, nil
|
|
}
|
|
|
|
// OneTimeCode represents special one-time codes stored in the database.
|
|
type OneTimeCode struct {
|
|
ID int `db:"id"`
|
|
PublicID uuid.UUID `db:"public_id"`
|
|
Signature string `db:"signature"`
|
|
IssuedAt time.Time `db:"issued"`
|
|
IssuedIP IP `db:"issued_ip"`
|
|
ExpiresAt time.Time `db:"expires"`
|
|
Username string `db:"username"`
|
|
Intent string `db:"intent"`
|
|
ConsumedAt sql.NullTime `db:"consumed"`
|
|
ConsumedIP NullIP `db:"consumed_ip"`
|
|
RevokedAt sql.NullTime `db:"revoked"`
|
|
RevokedIP NullIP `db:"revoked_ip"`
|
|
Code []byte `db:"code"`
|
|
}
|
|
|
|
// Consume sets the values required to consume the one-time code.
|
|
func (otp *OneTimeCode) Consume(ctx Context) {
|
|
otp.ConsumedAt = sql.NullTime{Valid: true, Time: ctx.GetClock().Now()}
|
|
otp.ConsumedIP = NewNullIP(ctx.RemoteIP())
|
|
}
|