Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SET PASSWORD FOR user = 'PASSWORD' #2158

Merged
merged 1 commit into from
Apr 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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