Add support for SET PASSWORD FOR user = 'PASSWORD'

Added support for the set password for user, so we can update user
password via the new server administration commands
pull/2158/head
Dejan Golja 2015-04-04 01:14:09 +11:00
parent f787755098
commit e1b9982401
5 changed files with 94 additions and 3 deletions

View File

@ -85,6 +85,7 @@ func (*ShowTagValuesStatement) node() {}
func (*ShowUsersStatement) node() {}
func (*RevokeStatement) node() {}
func (*SelectStatement) node() {}
func (*SetPasswordUserStatement) node() {}
func (*BinaryExpr) node() {}
func (*BooleanLiteral) node() {}
@ -179,6 +180,7 @@ func (*ShowTagValuesStatement) stmt() {}
func (*ShowUsersStatement) stmt() {}
func (*RevokeStatement) stmt() {}
func (*SelectStatement) stmt() {}
func (*SetPasswordUserStatement) stmt() {}
// Expr represents an expression that can be evaluated to a value.
type Expr interface {
@ -432,6 +434,30 @@ func (s *GrantStatement) RequiredPrivileges() ExecutionPrivileges {
return ExecutionPrivileges{{Name: "", Privilege: AllPrivileges}}
}
// SetPasswordUserStatement represents a command for chaning user password.
type SetPasswordUserStatement struct {
// Plain Password
Password string
// Who to grant the privilege to.
Name string
}
// String returns a string representation of the set password statement.
func (s *SetPasswordUserStatement) String() string {
var buf bytes.Buffer
_, _ = buf.WriteString("SET PASSWORD FOR ")
_, _ = buf.WriteString(s.Name)
_, _ = buf.WriteString(" = ")
_, _ = buf.WriteString(s.Password)
return buf.String()
}
// RequiredPrivileges returns the privilege required to execute a GrantStatement.
func (s *SetPasswordUserStatement) RequiredPrivileges() ExecutionPrivileges {
return ExecutionPrivileges{{Name: "", Privilege: AllPrivileges}}
}
// RevokeStatement represents a command to revoke a privilege from a user.
type RevokeStatement struct {
// Privilege to be revoked.

View File

@ -79,8 +79,10 @@ func (p *Parser) ParseStatement() (Statement, error) {
return p.parseRevokeStatement()
case ALTER:
return p.parseAlterStatement()
case SET:
return p.parseSetStatement()
default:
return nil, newParseError(tokstr(tok, lit), []string{"SELECT", "DELETE", "SHOW", "CREATE", "DROP", "GRANT", "REVOKE", "ALTER"}, pos)
return nil, newParseError(tokstr(tok, lit), []string{"SELECT", "DELETE", "SHOW", "CREATE", "DROP", "GRANT", "REVOKE", "ALTER", "SET"}, pos)
}
}
@ -189,6 +191,43 @@ func (p *Parser) parseAlterStatement() (Statement, error) {
return nil, newParseError(tokstr(tok, lit), []string{"RETENTION"}, pos)
}
// parseSetStatement parses a string and returns a set statement.
// This function assumes the SET token has already been consumed.
func (p *Parser) parseSetStatement() (*SetPasswordUserStatement, error) {
stmt := &SetPasswordUserStatement{}
// Consume the required PASSWORD token.
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != PASSWORD {
return nil, newParseError(tokstr(tok, lit), []string{"PASSWORD"}, pos)
}
// Consume the required FOR token.
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != FOR {
return nil, newParseError(tokstr(tok, lit), []string{"FOR"}, pos)
}
// Parse username
ident, err := p.parseIdent()
if err != nil {
return nil, err
}
stmt.Name = ident
// Consume the required = token.
if tok, pos, lit := p.scanIgnoreWhitespace(); tok != EQ {
return nil, newParseError(tokstr(tok, lit), []string{"="}, pos)
}
// Parse new user's password
if ident, err = p.parseString(); err != nil {
return nil, err
}
stmt.Password = ident
return stmt, nil
}
// parseCreateRetentionPolicyStatement parses a string and returns a create retention policy statement.
// This function assumes the CREATE RETENTION POLICY tokens have already been consumed.
func (p *Parser) parseCreateRetentionPolicyStatement() (*CreateRetentionPolicyStatement, error) {

View File

@ -649,6 +649,15 @@ func TestParser_ParseStatement(t *testing.T) {
},
},
// SET PASSWORD FOR USER
{
s: `SET PASSWORD FOR testuser = 'pwd1337'`,
stmt: &influxql.SetPasswordUserStatement{
Name: "testuser",
Password: "pwd1337",
},
},
// DROP CONTINUOUS QUERY statement
{
s: `DROP CONTINUOUS QUERY myquery ON foo`,
@ -877,9 +886,9 @@ func TestParser_ParseStatement(t *testing.T) {
},
// Errors
{s: ``, err: `found EOF, expected SELECT, DELETE, SHOW, CREATE, DROP, GRANT, REVOKE, ALTER at line 1, char 1`},
{s: ``, err: `found EOF, expected SELECT, DELETE, SHOW, CREATE, DROP, GRANT, REVOKE, ALTER, SET at line 1, char 1`},
{s: `SELECT`, err: `found EOF, expected identifier, string, number, bool at line 1, char 8`},
{s: `blah blah`, err: `found blah, expected SELECT, DELETE, SHOW, CREATE, DROP, GRANT, REVOKE, ALTER at line 1, char 1`},
{s: `blah blah`, err: `found blah, expected SELECT, DELETE, SHOW, CREATE, DROP, GRANT, REVOKE, ALTER, SET at line 1, char 1`},
{s: `SELECT field1 X`, err: `found X, expected FROM at line 1, char 15`},
{s: `SELECT field1 FROM "series" WHERE X +;`, err: `found ;, expected identifier, string, number, bool at line 1, char 38`},
{s: `SELECT field1 FROM myseries GROUP`, err: `found EOF, expected BY at line 1, char 35`},
@ -955,6 +964,13 @@ func TestParser_ParseStatement(t *testing.T) {
{s: `ALTER RETENTION POLICY`, err: `found EOF, expected identifier at line 1, char 24`},
{s: `ALTER RETENTION POLICY policy1`, err: `found EOF, expected ON at line 1, char 32`}, {s: `ALTER RETENTION POLICY policy1 ON`, err: `found EOF, expected identifier at line 1, char 35`},
{s: `ALTER RETENTION POLICY policy1 ON testdb`, err: `found EOF, expected DURATION, RETENTION, DEFAULT at line 1, char 42`},
{s: `SET`, err: `found EOF, expected PASSWORD at line 1, char 5`},
{s: `SET PASSWORD`, err: `found EOF, expected FOR at line 1, char 14`},
{s: `SET PASSWORD something`, err: `found something, expected FOR at line 1, char 14`},
{s: `SET PASSWORD FOR`, err: `found EOF, expected identifier at line 1, char 18`},
{s: `SET PASSWORD FOR dejan`, err: `found EOF, expected = at line 1, char 24`},
{s: `SET PASSWORD FOR dejan =`, err: `found EOF, expected string at line 1, char 25`},
{s: `SET PASSWORD FOR dejan = bla`, err: `found bla, expected string at line 1, char 26`},
}
for i, tt := range tests {

View File

@ -74,6 +74,7 @@ const (
EXISTS
EXPLAIN
FIELD
FOR
FROM
GRANT
GROUP
@ -104,6 +105,7 @@ const (
SELECT
SERIES
SERVERS
SET
SHOW
SLIMIT
STATS
@ -177,6 +179,7 @@ var tokens = [...]string{
EXISTS: "EXISTS",
EXPLAIN: "EXPLAIN",
FIELD: "FIELD",
FOR: "FOR",
FROM: "FROM",
GRANT: "GRANT",
GROUP: "GROUP",
@ -207,6 +210,7 @@ var tokens = [...]string{
SELECT: "SELECT",
SERIES: "SERIES",
SERVERS: "SERVERS",
SET: "SET",
SHOW: "SHOW",
SLIMIT: "SLIMIT",
SOFFSET: "SOFFSET",

View File

@ -2073,6 +2073,8 @@ func (s *Server) ExecuteQuery(q *influxql.Query, database string, user *User, ch
res = s.executeShowServersStatement(stmt, user)
case *influxql.CreateUserStatement:
res = s.executeCreateUserStatement(stmt, user)
case *influxql.SetPasswordUserStatement:
res = s.executeSetPasswordUserStatement(stmt, user)
case *influxql.DeleteStatement:
res = s.executeDeleteStatement()
case *influxql.DropUserStatement:
@ -2352,6 +2354,10 @@ func (s *Server) executeCreateUserStatement(q *influxql.CreateUserStatement, use
return &Result{Err: s.CreateUser(q.Name, q.Password, isAdmin)}
}
func (s *Server) executeSetPasswordUserStatement(q *influxql.SetPasswordUserStatement, user *User) *Result {
return &Result{Err: s.UpdateUser(q.Name, q.Password)}
}
func (s *Server) executeDropUserStatement(q *influxql.DropUserStatement, user *User) *Result {
return &Result{Err: s.DeleteUser(q.Name)}
}