Skip to content

Commit

Permalink
Add support for SET PASSWORD FOR user = 'PASSWORD'
Browse files Browse the repository at this point in the history
Added support for the set password for user, so we can update user
password via the new server administration commands
  • Loading branch information
dgolja committed Apr 4, 2015
1 parent f787755 commit e1b9982
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 3 deletions.
26 changes: 26 additions & 0 deletions influxql/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
41 changes: 40 additions & 1 deletion influxql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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) {
Expand Down
20 changes: 18 additions & 2 deletions influxql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand Down Expand Up @@ -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`},
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions influxql/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const (
EXISTS
EXPLAIN
FIELD
FOR
FROM
GRANT
GROUP
Expand Down Expand Up @@ -104,6 +105,7 @@ const (
SELECT
SERIES
SERVERS
SET
SHOW
SLIMIT
STATS
Expand Down Expand Up @@ -177,6 +179,7 @@ var tokens = [...]string{
EXISTS: "EXISTS",
EXPLAIN: "EXPLAIN",
FIELD: "FIELD",
FOR: "FOR",
FROM: "FROM",
GRANT: "GRANT",
GROUP: "GROUP",
Expand Down Expand Up @@ -207,6 +210,7 @@ var tokens = [...]string{
SELECT: "SELECT",
SERIES: "SERIES",
SERVERS: "SERVERS",
SET: "SET",
SHOW: "SHOW",
SLIMIT: "SLIMIT",
SOFFSET: "SOFFSET",
Expand Down
6 changes: 6 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)}
}
Expand Down

0 comments on commit e1b9982

Please sign in to comment.