Skip to content

Commit

Permalink
config typology update
Browse files Browse the repository at this point in the history
Signed-off-by: Abdul-Az <[email protected]>
  • Loading branch information
iamazzeez committed Apr 12, 2022
1 parent 4e5c55c commit 6d784e6
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 89 deletions.
26 changes: 13 additions & 13 deletions cmd/dex/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import (

// Config is the config format for the main application.
type Config struct {
Issuer string `json:"issuer"`
Storage Storage `json:"storage"`
Web Web `json:"web"`
Telemetry Telemetry `json:"telemetry"`
OAuth2 OAuth2 `json:"oauth2"`
GRPC GRPC `json:"grpc"`
Expiry Expiry `json:"expiry"`
InvalidAttempts InvalidAttempts `json:"invalidAttempts`
Logger Logger `json:"logger"`
Issuer string `json:"issuer"`
Storage Storage `json:"storage"`
Web Web `json:"web"`
Telemetry Telemetry `json:"telemetry"`
OAuth2 OAuth2 `json:"oauth2"`
GRPC GRPC `json:"grpc"`
Expiry Expiry `json:"expiry"`
InvalidLoginAttempts InvalidLoginAttempts `json:"invalidLoginAttempts`
Logger Logger `json:"logger"`

Frontend server.WebConfig `json:"frontend"`

Expand Down Expand Up @@ -293,8 +293,8 @@ type Logger struct {
Format string `json:"format"`
}

type InvalidAttempts struct {
EnableInvalidAttempts bool `json:"enableInvalidAttempts"`
BlockDuration int32 `json:"blockDuration"`
MaxAttemptsAllowed int32 `json:"maxAttemptsAllowed"`
type InvalidLoginAttempts struct {
EnableInvalidLoginAttempts bool `json:"enableInvalidLoginAttempts"`
BlockedDuration int32 `json:"blockedDuration"`
MaxInvalidLoginAttemptsAllowed int32 `json:"maxInvalidLoginAttemptsAllowed"`
}
8 changes: 4 additions & 4 deletions cmd/dex/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ func serve(cmd *cobra.Command, args []string) error {
serverConfig.IDTokensValidFor = idTokens
}

if c.InvalidAttempts.EnableInvalidAttempts {
serverConfig.EnableInvalidAttempts = c.InvalidAttempts.EnableInvalidAttempts
serverConfig.BlockDuration = c.InvalidAttempts.BlockDuration
serverConfig.MaxAttemptsAllowed = c.InvalidAttempts.MaxAttemptsAllowed
if c.InvalidLoginAttempts.EnableInvalidLoginAttempts {
serverConfig.EnableInvalidLoginAttempts = c.InvalidLoginAttempts.EnableInvalidLoginAttempts
serverConfig.BlockedDuration = c.InvalidLoginAttempts.BlockedDuration
serverConfig.MaxInvalidLoginAttemptsAllowed = c.InvalidLoginAttempts.MaxInvalidLoginAttemptsAllowed
}

if c.Expiry.AuthRequests != "" {
Expand Down
30 changes: 15 additions & 15 deletions server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,15 @@ func (s *Server) discoveryHandler() (http.HandlerFunc, error) {
}

func (s *Server) isFailedAttemptDurationExceeded(u storage.InvalidLoginAttempt) bool {
if diff := time.Since(u.UpdatedAt); diff.Minutes() > float64(s.blockDuration) {
if diff := time.Since(u.UpdatedAt); diff.Minutes() > float64(s.blockedDuration) {
return true
}
return false
}

func (s *Server) resetFailedAttempt(username string, w http.ResponseWriter, r *http.Request) {
updater := func(u storage.InvalidLoginAttempt) (storage.InvalidLoginAttempt, error) {
u.InvalidAttemptsCount = 1
u.InvalidLoginAttemptsCount = 1
u.UpdatedAt = time.Now()
return u, nil
}
Expand All @@ -231,20 +231,20 @@ func (s *Server) resetFailedAttempt(username string, w http.ResponseWriter, r *h
}

func (s *Server) isAllowedFailedAttemptExceeded(u storage.InvalidLoginAttempt) bool {
return u.InvalidAttemptsCount >= s.maxAttemptsAllowed
return u.InvalidLoginAttemptsCount >= s.maxInvalidLoginAttemptsAllowed
}

func (s *Server) isUserBlocked(u storage.InvalidLoginAttempt) bool {
diff := time.Since(u.UpdatedAt)
if diff.Minutes() <= float64(s.blockDuration) && u.InvalidAttemptsCount >= s.maxAttemptsAllowed {
if diff.Minutes() <= float64(s.blockedDuration) && u.InvalidLoginAttemptsCount >= s.maxInvalidLoginAttemptsAllowed {
return true
}
return false
}

func (s *Server) updateInvalidAttemptCount(username string, w http.ResponseWriter, r *http.Request) {
updater := func(u storage.InvalidLoginAttempt) (storage.InvalidLoginAttempt, error) {
u.InvalidAttemptsCount = u.InvalidAttemptsCount + 1
u.InvalidLoginAttemptsCount = u.InvalidLoginAttemptsCount + 1
u.UpdatedAt = time.Now()
return u, nil
}
Expand Down Expand Up @@ -398,7 +398,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
}
http.Redirect(w, r, callbackURL, http.StatusFound)
case connector.PasswordConnector:
if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(conn), false, showBacklink, 0, s.maxAttemptsAllowed, s.blockDuration); err != nil {
if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(conn), false, showBacklink, 0, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
case connector.SAMLConnector:
Expand Down Expand Up @@ -449,7 +449,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {

if s.isUserBlocked(InvalidLoginAttempt) {
s.logger.Errorf("User is blocked")
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidAttemptsCount, s.maxAttemptsAllowed, s.blockDuration); err != nil {
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidLoginAttemptsCount, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
return
Expand All @@ -465,9 +465,9 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
if InvalidLoginAttempt.Username != username {
//create InvalidLoginAttempt
err := s.storage.CreateInvalidLoginAttempt(storage.InvalidLoginAttempt{
Username: username,
InvalidAttemptsCount: 1,
UpdatedAt: time.Now(),
Username: username,
InvalidLoginAttemptsCount: 1,
UpdatedAt: time.Now(),
})

if err != nil {
Expand All @@ -476,31 +476,31 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
return
}

if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, 1, s.maxAttemptsAllowed, s.blockDuration); err != nil {
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, 1, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
return
}

if s.isFailedAttemptDurationExceeded(InvalidLoginAttempt) {
s.resetFailedAttempt(username, w, r)
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, 1, s.maxAttemptsAllowed, s.blockDuration); err != nil {
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, 1, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
return
}

if s.isAllowedFailedAttemptExceeded(InvalidLoginAttempt) {
s.logger.Errorf("User is blocked: %v", InvalidLoginAttempt.InvalidAttemptsCount)
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidAttemptsCount, s.maxAttemptsAllowed, s.blockDuration); err != nil {
s.logger.Errorf("User is blocked: %v", InvalidLoginAttempt.InvalidLoginAttemptsCount)
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidLoginAttemptsCount, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
return
}

s.updateInvalidAttemptCount(username, w, r)

if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidAttemptsCount+1, s.maxAttemptsAllowed, s.blockDuration); err != nil {
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, InvalidLoginAttempt.InvalidLoginAttemptsCount+1, s.maxInvalidLoginAttemptsAllowed, s.blockedDuration); err != nil {
s.logger.Errorf("Server template error: %v", err)
}
return
Expand Down
44 changes: 22 additions & 22 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ type Config struct {
AuthRequestsValidFor time.Duration // Defaults to 24 hours
DeviceRequestsValidFor time.Duration // Defaults to 5 minutes

EnableInvalidAttempts bool
BlockDuration int32
MaxAttemptsAllowed int32
EnableInvalidLoginAttempts bool
BlockedDuration int32
MaxInvalidLoginAttemptsAllowed int32
// If set, the server will use this connector to handle password grants
PasswordConnector string

Expand Down Expand Up @@ -166,9 +166,9 @@ type Server struct {
authRequestsValidFor time.Duration
deviceRequestsValidFor time.Duration

enableInvalidAttempts bool
blockDuration int32
maxAttemptsAllowed int32
enableInvalidLoginAttempts bool
blockedDuration int32
maxInvalidLoginAttemptsAllowed int32

logger log.Logger
}
Expand Down Expand Up @@ -231,22 +231,22 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
}

s := &Server{
issuerURL: *issuerURL,
connectors: make(map[string]Connector),
storage: newKeyCacher(c.Storage, now),
supportedResponseTypes: supported,
idTokensValidFor: value(c.IDTokensValidFor, 24*time.Hour),
authRequestsValidFor: value(c.AuthRequestsValidFor, 24*time.Hour),
deviceRequestsValidFor: value(c.DeviceRequestsValidFor, 5*time.Minute),
skipApproval: c.SkipApprovalScreen,
alwaysShowLogin: c.AlwaysShowLoginScreen,
now: now,
templates: tmpls,
passwordConnector: c.PasswordConnector,
logger: c.Logger,
enableInvalidAttempts: c.EnableInvalidAttempts,
blockDuration: c.BlockDuration,
maxAttemptsAllowed: c.MaxAttemptsAllowed,
issuerURL: *issuerURL,
connectors: make(map[string]Connector),
storage: newKeyCacher(c.Storage, now),
supportedResponseTypes: supported,
idTokensValidFor: value(c.IDTokensValidFor, 24*time.Hour),
authRequestsValidFor: value(c.AuthRequestsValidFor, 24*time.Hour),
deviceRequestsValidFor: value(c.DeviceRequestsValidFor, 5*time.Minute),
skipApproval: c.SkipApprovalScreen,
alwaysShowLogin: c.AlwaysShowLoginScreen,
now: now,
templates: tmpls,
passwordConnector: c.PasswordConnector,
logger: c.Logger,
enableInvalidLoginAttempts: c.EnableInvalidLoginAttempts,
blockedDuration: c.BlockedDuration,
maxInvalidLoginAttemptsAllowed: c.MaxInvalidLoginAttemptsAllowed,
}

// Retrieves connector objects in backend storage. This list includes the static connectors
Expand Down
22 changes: 11 additions & 11 deletions server/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,18 +284,18 @@ func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []c
return renderTemplate(w, t.loginTmpl, data)
}

func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid, showBacklink bool, invalidAttemptsCount int32, maxAttemptsAllowed int32, blockDuration int32) error {
func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid, showBacklink bool, InvalidLoginAttemptsCount int32, maxInvalidLoginAttemptsAllowed int32, blockedDuration int32) error {
data := struct {
PostURL string
BackLink bool
Username string
UsernamePrompt string
Invalid bool
ReqPath string
InvalidAttemptsCount int32
MaxAttemptsAllowed int32
BlockDuration int32
}{postURL, showBacklink, lastUsername, usernamePrompt, lastWasInvalid, r.URL.Path, invalidAttemptsCount, maxAttemptsAllowed, blockDuration}
PostURL string
BackLink bool
Username string
UsernamePrompt string
Invalid bool
ReqPath string
InvalidLoginAttemptsCount int32
MaxInvalidLoginAttemptsAllowed int32
BlockedDuration int32
}{postURL, showBacklink, lastUsername, usernamePrompt, lastWasInvalid, r.URL.Path, InvalidLoginAttemptsCount, maxInvalidLoginAttemptsAllowed, blockedDuration}
return renderTemplate(w, t.passwordTmpl, data)
}

Expand Down
2 changes: 1 addition & 1 deletion storage/kubernetes/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ func (cli *client) UpdateInvalidLoginAttempt(username string, updater func(old s
if err != nil {
return err
}
updated.InvalidAttemptsCount = u.InvalidAttemptsCount
updated.InvalidLoginAttemptsCount = u.InvalidLoginAttemptsCount
updated.UpdatedAt = u.UpdatedAt

newInvalidLoginAttempt := cli.fromStorageInvalidLoginAttempt(updated)
Expand Down
17 changes: 8 additions & 9 deletions storage/kubernetes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,8 @@ type InvalidLoginAttempt struct {
// This field is IMMUTABLE. Do not change.
Username string `json:"username,omitempty"`

InvalidAttemptsCount int32 `json:"invalid_attempts_count,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
InvalidLoginAttemptsCount int32 `json:"invalid_login_attempts_count,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}

// PasswordList is a list of Passwords.
Expand Down Expand Up @@ -439,17 +438,17 @@ func (cli *client) fromStorageInvalidLoginAttempt(u storage.InvalidLoginAttempt)
Name: cli.idToName(username),
Namespace: cli.namespace,
},
Username: username,
InvalidAttemptsCount: u.InvalidAttemptsCount,
UpdatedAt: u.UpdatedAt,
Username: username,
InvalidLoginAttemptsCount: u.InvalidLoginAttemptsCount,
UpdatedAt: u.UpdatedAt,
}
}

func toStorageInvalidLoginAttempt(u InvalidLoginAttempt) storage.InvalidLoginAttempt {
return storage.InvalidLoginAttempt{
Username: u.Username,
InvalidAttemptsCount: u.InvalidAttemptsCount,
UpdatedAt: u.UpdatedAt,
Username: u.Username,
InvalidLoginAttemptsCount: u.InvalidLoginAttemptsCount,
UpdatedAt: u.UpdatedAt,
}
}

Expand Down
10 changes: 5 additions & 5 deletions storage/memory/static_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@ func TestStaticBlockedUsers(t *testing.T) {
}
backing := New(logger)

u1 := storage.InvalidLoginAttempt{Username: "foo_secret", InvalidAttemptsCount: 0}
u2 := storage.InvalidLoginAttempt{Username: "bar_secret", InvalidAttemptsCount: 4}
u3 := storage.InvalidLoginAttempt{Username: "spam_secret", InvalidAttemptsCount: 2}
u4 := storage.InvalidLoginAttempt{Username: "Spam_secret", InvalidAttemptsCount: 5}
u1 := storage.InvalidLoginAttempt{Username: "foo_secret", InvalidLoginAttemptsCount: 0}
u2 := storage.InvalidLoginAttempt{Username: "bar_secret", InvalidLoginAttemptsCount: 4}
u3 := storage.InvalidLoginAttempt{Username: "spam_secret", InvalidLoginAttemptsCount: 2}
u4 := storage.InvalidLoginAttempt{Username: "Spam_secret", InvalidLoginAttemptsCount: 5}

backing.CreateInvalidLoginAttempt(u1)
s := storage.WithStaticInvalidLoginAttempt(backing, []storage.InvalidLoginAttempt{u2}, logger)
Expand Down Expand Up @@ -268,7 +268,7 @@ func TestStaticBlockedUsers(t *testing.T) {
name: "update non-static InvalidLoginAttempt",
action: func() error {
updater := func(u storage.InvalidLoginAttempt) (storage.InvalidLoginAttempt, error) {
u.InvalidAttemptsCount = u.InvalidAttemptsCount + 1
u.InvalidLoginAttemptsCount = u.InvalidLoginAttemptsCount + 1
u.UpdatedAt = time.Now()
return u, nil
}
Expand Down
12 changes: 6 additions & 6 deletions storage/sql/crud.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,10 @@ func (c *conn) UpdateInvalidLoginAttempt(username string, updater func(old stora
_, err = tx.Exec(`
update invalid_login_attempts
set
InvalidLoginAttempt = $1,
invalid_login_attempts_count = $1,
updated_at = $2
where username = $3;
`, nu.InvalidAttemptsCount, nu.UpdatedAt, username,
`, nu.InvalidLoginAttemptsCount, nu.UpdatedAt, username,
)
if err != nil {
return fmt.Errorf("update invalid_login_attempts: %v", err)
Expand Down Expand Up @@ -564,11 +564,11 @@ func (c *conn) CreateClient(cli storage.Client) error {
func (c *conn) CreateInvalidLoginAttempt(u storage.InvalidLoginAttempt) error {
_, err := c.Exec(`
insert into invalid_login_attempts (
username, invalid_attempts_count, updated_at
username, invalid_login_attempts_count, updated_at
)
values ($1, $2, $3);
`,
strings.ToLower(u.Username), u.InvalidAttemptsCount, u.UpdatedAt,
strings.ToLower(u.Username), u.InvalidLoginAttemptsCount, u.UpdatedAt,
)
if err != nil {
if c.alreadyExistsCheck(err) {
Expand Down Expand Up @@ -690,7 +690,7 @@ func (c *conn) GetInvalidLoginAttempt(username string) (storage.InvalidLoginAtte
func getInvalidLoginAttempt(q querier, username string) (u storage.InvalidLoginAttempt, err error) {
return scanInvalidLoginAttempt(q.QueryRow(`
select
username, invalid_attempts_count, updated_at
username, invalid_login_attempts_count, updated_at
from invalid_login_attempts where username = $1;
`, strings.ToLower(username)))
}
Expand Down Expand Up @@ -742,7 +742,7 @@ func scanPassword(s scanner) (p storage.Password, err error) {

func scanInvalidLoginAttempt(s scanner) (u storage.InvalidLoginAttempt, err error) {
err = s.Scan(
&u.Username, &u.InvalidAttemptsCount, &u.UpdatedAt,
&u.Username, &u.InvalidLoginAttemptsCount, &u.UpdatedAt,
)
if err != nil {
if err == sql.ErrNoRows {
Expand Down
6 changes: 3 additions & 3 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ type GCResult struct {
}

type InvalidLoginAttempt struct {
Username string
InvalidAttemptsCount int32
UpdatedAt time.Time
Username string
InvalidLoginAttemptsCount int32
UpdatedAt time.Time
}

// Storage is the storage interface used by the server. Implementations are
Expand Down

0 comments on commit 6d784e6

Please sign in to comment.