fix #3102: add authentication cache

pull/3161/head
David Norton 2015-06-26 15:30:00 -04:00 committed by Philip O'Toole
parent 9198cbd65a
commit debc3cc11c
3 changed files with 23 additions and 14 deletions

View File

@ -92,6 +92,9 @@ func (*DropRetentionPolicyStatement) node() {}
func (*DropSeriesStatement) node() {} func (*DropSeriesStatement) node() {}
func (*DropUserStatement) node() {} func (*DropUserStatement) node() {}
func (*GrantStatement) node() {} func (*GrantStatement) node() {}
func (*RevokeStatement) node() {}
func (*SelectStatement) node() {}
func (*SetPasswordUserStatement) node() {}
func (*ShowContinuousQueriesStatement) node() {} func (*ShowContinuousQueriesStatement) node() {}
func (*ShowGrantsForUserStatement) node() {} func (*ShowGrantsForUserStatement) node() {}
func (*ShowServersStatement) node() {} func (*ShowServersStatement) node() {}
@ -105,9 +108,6 @@ func (*ShowDiagnosticsStatement) node() {}
func (*ShowTagKeysStatement) node() {} func (*ShowTagKeysStatement) node() {}
func (*ShowTagValuesStatement) node() {} func (*ShowTagValuesStatement) node() {}
func (*ShowUsersStatement) node() {} func (*ShowUsersStatement) node() {}
func (*RevokeStatement) node() {}
func (*SelectStatement) node() {}
func (*SetPasswordUserStatement) node() {}
func (*BinaryExpr) node() {} func (*BinaryExpr) node() {}
func (*BooleanLiteral) node() {} func (*BooleanLiteral) node() {}

View File

@ -94,7 +94,7 @@ func (p *Parser) ParseStatement() (Statement, error) {
case ALTER: case ALTER:
return p.parseAlterStatement() return p.parseAlterStatement()
case SET: case SET:
return p.parseSetStatement() return p.parseSetPasswordUserStatement()
default: default:
return nil, newParseError(tokstr(tok, lit), []string{"SELECT", "DELETE", "SHOW", "CREATE", "DROP", "GRANT", "REVOKE", "ALTER", "SET"}, pos) return nil, newParseError(tokstr(tok, lit), []string{"SELECT", "DELETE", "SHOW", "CREATE", "DROP", "GRANT", "REVOKE", "ALTER", "SET"}, pos)
} }
@ -207,19 +207,14 @@ func (p *Parser) parseAlterStatement() (Statement, error) {
return nil, newParseError(tokstr(tok, lit), []string{"RETENTION"}, pos) return nil, newParseError(tokstr(tok, lit), []string{"RETENTION"}, pos)
} }
// parseSetStatement parses a string and returns a set statement. // parseSetPasswordUserStatement parses a string and returns a set statement.
// This function assumes the SET token has already been consumed. // This function assumes the SET token has already been consumed.
func (p *Parser) parseSetStatement() (*SetPasswordUserStatement, error) { func (p *Parser) parseSetPasswordUserStatement() (*SetPasswordUserStatement, error) {
stmt := &SetPasswordUserStatement{} stmt := &SetPasswordUserStatement{}
// Consume the required PASSWORD token. // Consume the required PASSWORD FOR tokens.
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != PASSWORD { if err := p.parseTokens([]Token{PASSWORD, FOR}); err != nil {
return nil, newParseError(tokstr(tok, lit), []string{"PASSWORD"}, pos) return nil, err
}
// Consume the required FOR token.
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != FOR {
return nil, newParseError(tokstr(tok, lit), []string{"FOR"}, pos)
} }
// Parse username // Parse username

View File

@ -96,6 +96,9 @@ type Store struct {
// The amount of time without an apply before sending a heartbeat. // The amount of time without an apply before sending a heartbeat.
CommitTimeout time.Duration CommitTimeout time.Duration
// Authentication cache.
authCache map[string]string
Logger *log.Logger Logger *log.Logger
} }
@ -116,6 +119,7 @@ func NewStore(c Config) *Store {
ElectionTimeout: time.Duration(c.ElectionTimeout), ElectionTimeout: time.Duration(c.ElectionTimeout),
LeaderLeaseTimeout: time.Duration(c.LeaderLeaseTimeout), LeaderLeaseTimeout: time.Duration(c.LeaderLeaseTimeout),
CommitTimeout: time.Duration(c.CommitTimeout), CommitTimeout: time.Duration(c.CommitTimeout),
authCache: make(map[string]string, 0),
Logger: log.New(os.Stderr, "", log.LstdFlags), Logger: log.New(os.Stderr, "", log.LstdFlags),
} }
} }
@ -994,11 +998,19 @@ func (s *Store) Authenticate(username, password string) (ui *UserInfo, err error
return ErrUserNotFound return ErrUserNotFound
} }
// Check the local auth cache first.
if p, ok := s.authCache[username]; ok && p == password {
ui = u
return nil
}
// Compare password with user hash. // Compare password with user hash.
if err := bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(password)); err != nil { if err := bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(password)); err != nil {
return err return err
} }
s.authCache[username] = password
ui = u ui = u
return nil return nil
}) })
@ -1578,6 +1590,7 @@ func (fsm *storeFSM) applyDropUserCommand(cmd *internal.Command) interface{} {
return err return err
} }
fsm.data = other fsm.data = other
delete(fsm.authCache, v.GetName())
return nil return nil
} }
@ -1591,6 +1604,7 @@ func (fsm *storeFSM) applyUpdateUserCommand(cmd *internal.Command) interface{} {
return err return err
} }
fsm.data = other fsm.data = other
delete(fsm.authCache, v.GetName())
return nil return nil
} }