Add password changing for OSS users

pull/101/head
Chris Goller 2017-02-22 00:36:28 -06:00
parent 72dbae043f
commit 87a139c8e5
2 changed files with 100 additions and 12 deletions

View File

@ -72,6 +72,12 @@ func (c *Client) Get(ctx context.Context, name string) (*chronograf.User, error)
// Update the user's permissions or roles
func (c *Client) Update(ctx context.Context, u *chronograf.User) error {
// Only allow one type of change at a time. If it is a password
// change then do it and return without any changes to permissions
if u.Passwd != "" {
return c.updatePassword(ctx, u.Name, u.Passwd)
}
user, err := c.Get(ctx, u.Name)
if err != nil {
return err
@ -176,3 +182,31 @@ func (c *Client) userPermissions(ctx context.Context, name string) (chronograf.P
}
return results.Permissions(), nil
}
func (c *Client) updatePassword(ctx context.Context, name, passwd string) error {
res, err := c.Query(ctx, chronograf.Query{
Command: fmt.Sprintf(`SET PASSWORD for "%s" = '%s'`, name, passwd),
})
if err != nil {
return err
}
// The SET PASSWORD statements puts the error within the results itself
// So, we have to crack open the results to see what happens
octets, err := res.MarshalJSON()
if err != nil {
return err
}
results := make([]struct{ Error string }, 0)
if err := json.Unmarshal(octets, &results); err != nil {
return err
}
// At last, we can check if there are any error strings
for _, r := range results {
if r.Error != "" {
return fmt.Errorf(r.Error)
}
}
return nil
}

View File

@ -641,19 +641,70 @@ func TestClient_Update(t *testing.T) {
u *chronograf.User
}
tests := []struct {
name string
statusUsers int
showUsers []byte
statusGrants int
showGrants []byte
statusRevoke int
revoke []byte
statusGrant int
grant []byte
args args
want []string
wantErr bool
name string
statusUsers int
showUsers []byte
statusGrants int
showGrants []byte
statusRevoke int
revoke []byte
statusGrant int
grant []byte
statusPassword int
password []byte
args args
want []string
wantErr bool
}{
{
name: "Change Password",
statusPassword: http.StatusOK,
password: []byte(`{"results":[]}`),
args: args{
ctx: context.Background(),
u: &chronograf.User{
Name: "docbrown",
Passwd: "hunter2",
},
},
want: []string{
`SET PASSWORD for "docbrown" = 'hunter2'`,
},
},
{
name: "Grant all permissions",
statusUsers: http.StatusOK,
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
statusGrants: http.StatusOK,
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
statusRevoke: http.StatusOK,
revoke: []byte(`{"results":[]}`),
statusGrant: http.StatusOK,
grant: []byte(`{"results":[]}`),
args: args{
ctx: context.Background(),
u: &chronograf.User{
Name: "docbrown",
Permissions: chronograf.Permissions{
{
Scope: "all",
Allowed: []string{"WRITE", "READ"},
},
{
Scope: "database",
Name: "mydb",
Allowed: []string{"WRITE", "READ"},
},
},
},
},
want: []string{
`SHOW USERS`,
`SHOW GRANTS FOR "docbrown"`,
`GRANT ALL PRIVILEGES TO "docbrown"`,
`GRANT ALL ON "mydb" TO "docbrown"`,
},
},
{
name: "Revoke all permissions",
statusUsers: http.StatusOK,
@ -870,6 +921,9 @@ func TestClient_Update(t *testing.T) {
} else if strings.Contains(query, "GRANT") {
rw.WriteHeader(tt.statusGrant)
rw.Write(tt.grant)
} else if strings.Contains(query, "PASSWORD") {
rw.WriteHeader(tt.statusPassword)
rw.Write(tt.password)
}
queries = append(queries, query)
}))