*: Rename security to auth

This commit is contained in:
Barak Michener 2015-06-15 18:15:51 -04:00
parent e20b487904
commit 64ec8af91b
14 changed files with 234 additions and 234 deletions

View File

@ -12,7 +12,7 @@ There are three types of resources in etcd
#### Users
A user is an identity to be authenticated. Each user can have multiple roles. The user has a capability (such as reading or writing) on the resource if one of the roles has that capability.
A user named `root` is required before security can be enabled, and it always has the ROOT role. The ROOT role can be granted to multiple users, but `root` is required for recovery purposes.
A user named `root` is required before authentication can be enabled, and it always has the ROOT role. The ROOT role can be granted to multiple users, but `root` is required for recovery purposes.
#### Roles
Each role has exact one associated Permission List. An permission list exists for each permission on key-value resources.
@ -35,7 +35,7 @@ A permission on `/foo` is for that exact key or directory, not its children or r
### Settings Resources
Specific settings for the cluster as a whole. This can include adding and removing cluster members, enabling or disabling security, replacing certificates, and any other dynamic configuration by the administrator (holder of the ROOT role).
Specific settings for the cluster as a whole. This can include adding and removing cluster members, enabling or disabling authentication, replacing certificates, and any other dynamic configuration by the administrator (holder of the ROOT role).
## v2 Auth
@ -43,7 +43,7 @@ Specific settings for the cluster as a whole. This can include adding and removi
We only support [Basic Auth](http://en.wikipedia.org/wiki/Basic_access_authentication) for the first version. Client needs to attach the basic auth to the HTTP Authorization Header.
### Authorization field for operations
Added to requests to /v2/keys, /v2/security
Added to requests to /v2/keys, /v2/auth
Add code 403 Forbidden to the set of responses from the v2 API
Authorization: Basic {encoded string}
@ -86,7 +86,7 @@ Password is only passed when necessary. Last Modified is set by the server and i
**Get a list of users**
GET/HEAD /v2/security/user
GET/HEAD /v2/auth/user
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -102,7 +102,7 @@ GET/HEAD /v2/security/user
**Get User Details**
GET/HEAD /v2/security/users/alice
GET/HEAD /v2/auth/users/alice
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -122,7 +122,7 @@ GET/HEAD /v2/security/users/alice
A user can be created with initial roles, if filled in. However, no roles are required; only the username and password fields
PUT /v2/security/users/charlie
PUT /v2/auth/users/charlie
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -138,7 +138,7 @@ PUT /v2/security/users/charlie
**Remove A User**
DELETE /v2/security/users/charlie
DELETE /v2/auth/users/charlie
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -169,7 +169,7 @@ A full role structure may look like this. A Permission List structure is used fo
**Get a list of Roles**
GET/HEAD /v2/security/roles
GET/HEAD /v2/auth/roles
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -186,7 +186,7 @@ GET/HEAD /v2/security/roles
**Get Role Details**
GET/HEAD /v2/security/roles/fleet
GET/HEAD /v2/auth/roles/fleet
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -210,7 +210,7 @@ GET/HEAD /v2/security/roles/fleet
**Create Or Update A Role**
PUT /v2/security/roles/rocket
PUT /v2/auth/roles/rocket
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -228,7 +228,7 @@ PUT /v2/security/roles/rocket
**Remove A Role**
DELETE /v2/security/roles/rocket
DELETE /v2/auth/roles/rocket
Sent Headers:
Authorization: Basic <BasicAuthString>
@ -240,11 +240,11 @@ DELETE /v2/security/roles/rocket
200 Body: (empty)
#### Enable and Disable Security
#### Enable and Disable Authentication
**Get security status**
**Get auth status**
GET /v2/security/enable
GET /v2/auth/enable
Sent Headers:
Possible Status Codes:
@ -255,9 +255,9 @@ GET /v2/security/enable
}
**Enable security**
**Enable auth**
PUT /v2/security/enable
PUT /v2/auth/enable
Sent Headers:
Put Body: (empty)
@ -266,9 +266,9 @@ PUT /v2/security/enable
400 Bad Request (if not a root user)
200 Body: (empty)
**Disable security**
**Disable auth**
DELETE /v2/security/enable
DELETE /v2/auth/enable
Sent Headers:
Authorization: Basic <RootAuthString>
@ -282,10 +282,10 @@ DELETE /v2/security/enable
Let's walk through an example to show two tenants (applications, in our case) using etcd permissions.
### Enable security
### Enable auth
```
PUT /v2/security/enable
PUT /v2/auth/enable
Headers:
Put Body:
{"user" : "root", "password": "root"}
@ -295,7 +295,7 @@ PUT /v2/security/enable
### Change root's password
```
PUT /v2/security/users/root
PUT /v2/auth/users/root
Headers:
Authorization: Basic <root:root>
Put Body:
@ -307,7 +307,7 @@ PUT /v2/security/users/root
Create the rocket role fully specified:
```
PUT /v2/security/roles/rocket
PUT /v2/auth/roles/rocket
Headers:
Authorization: Basic <root:betterRootPW!>
Body:
@ -329,7 +329,7 @@ PUT /v2/security/roles/rocket
But let's make fleet just a basic role for now:
```
PUT /v2/security/roles/fleet
PUT /v2/auth/roles/fleet
Headers:
Authorization: Basic <root:betterRootPW!>
Body:
@ -345,7 +345,7 @@ Well, we finally figured out where we want fleet to live. Let's fix it.
```
PUT /v2/security/roles/fleet
PUT /v2/auth/roles/fleet
Headers:
Authorization: Basic <root:betterRootPW!>
Put Body:
@ -367,7 +367,7 @@ PUT /v2/security/roles/fleet
Same as before, let's use rocket all at once and fleet separately
```
PUT /v2/security/users/rocketuser
PUT /v2/auth/users/rocketuser
Headers:
Authorization: Basic <root:betterRootPW!>
Body:
@ -375,7 +375,7 @@ PUT /v2/security/users/rocketuser
```
```
PUT /v2/security/users/fleetuser
PUT /v2/auth/users/fleetuser
Headers:
Authorization: Basic <root:betterRootPW!>
Body:
@ -387,7 +387,7 @@ PUT /v2/security/users/fleetuser
Likewise, let's explicitly grant fleetuser access.
```
PUT /v2/security/users/fleetuser
PUT /v2/auth/users/fleetuser
Headers:
Authorization: Basic <root:betterRootPW!>
Body:

View File

@ -47,15 +47,15 @@ const (
ReadWritePermission
)
// NewSecurityRoleAPI constructs a new SecurityRoleAPI that uses HTTP to
// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to
// interact with etcd's role creation and modification features.
func NewSecurityRoleAPI(c Client) SecurityRoleAPI {
return &httpSecurityRoleAPI{
func NewAuthRoleAPI(c Client) AuthRoleAPI {
return &httpAuthRoleAPI{
client: c,
}
}
type SecurityRoleAPI interface {
type AuthRoleAPI interface {
// Add a role.
AddRole(ctx context.Context, role string) error
@ -75,27 +75,27 @@ type SecurityRoleAPI interface {
ListRoles(ctx context.Context) ([]string, error)
}
type httpSecurityRoleAPI struct {
type httpAuthRoleAPI struct {
client httpClient
}
type securityRoleAPIAction struct {
type authRoleAPIAction struct {
verb string
name string
role *Role
}
type securityRoleAPIList struct{}
type authRoleAPIList struct{}
func (list *securityRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2SecurityURL(ep, "roles", "")
func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "roles", "")
req, _ := http.NewRequest("GET", u.String(), nil)
req.Header.Set("Content-Type", "application/json")
return req
}
func (l *securityRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2SecurityURL(ep, "roles", l.name)
func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "roles", l.name)
if l.role == nil {
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
@ -110,8 +110,8 @@ func (l *securityRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
return req
}
func (r *httpSecurityRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
resp, body, err := r.client.Do(ctx, &securityRoleAPIList{})
func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
resp, body, err := r.client.Do(ctx, &authRoleAPIList{})
if err != nil {
return nil, err
}
@ -128,31 +128,31 @@ func (r *httpSecurityRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
return userList.Roles, nil
}
func (r *httpSecurityRoleAPI) AddRole(ctx context.Context, rolename string) error {
func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error {
role := &Role{
Role: rolename,
}
return r.addRemoveRole(ctx, &securityRoleAPIAction{
return r.addRemoveRole(ctx, &authRoleAPIAction{
verb: "PUT",
name: rolename,
role: role,
})
}
func (r *httpSecurityRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
return r.addRemoveRole(ctx, &securityRoleAPIAction{
func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
return r.addRemoveRole(ctx, &authRoleAPIAction{
verb: "DELETE",
name: rolename,
})
}
func (r *httpSecurityRoleAPI) addRemoveRole(ctx context.Context, req *securityRoleAPIAction) error {
func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error {
resp, body, err := r.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return err
@ -162,8 +162,8 @@ func (r *httpSecurityRoleAPI) addRemoveRole(ctx context.Context, req *securityRo
return nil
}
func (r *httpSecurityRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
return r.modRole(ctx, &securityRoleAPIAction{
func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
return r.modRole(ctx, &authRoleAPIAction{
verb: "GET",
name: rolename,
})
@ -183,7 +183,7 @@ func buildRWPermission(prefixes []string, permType PermissionType) rwPermission
return out
}
func (r *httpSecurityRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
rwp := buildRWPermission(prefixes, permType)
role := &Role{
Role: rolename,
@ -191,14 +191,14 @@ func (r *httpSecurityRoleAPI) GrantRoleKV(ctx context.Context, rolename string,
KV: rwp,
},
}
return r.modRole(ctx, &securityRoleAPIAction{
return r.modRole(ctx, &authRoleAPIAction{
verb: "PUT",
name: rolename,
role: role,
})
}
func (r *httpSecurityRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
rwp := buildRWPermission(prefixes, permType)
role := &Role{
Role: rolename,
@ -206,20 +206,20 @@ func (r *httpSecurityRoleAPI) RevokeRoleKV(ctx context.Context, rolename string,
KV: rwp,
},
}
return r.modRole(ctx, &securityRoleAPIAction{
return r.modRole(ctx, &authRoleAPIAction{
verb: "PUT",
name: rolename,
role: role,
})
}
func (r *httpSecurityRoleAPI) modRole(ctx context.Context, req *securityRoleAPIAction) (*Role, error) {
func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) {
resp, body, err := r.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return nil, err

View File

@ -25,7 +25,7 @@ import (
)
var (
defaultV2SecurityPrefix = "/v2/security"
defaultV2AuthPrefix = "/v2/auth"
)
type User struct {
@ -36,50 +36,50 @@ type User struct {
Revoke []string `json:"revoke,omitempty"`
}
func v2SecurityURL(ep url.URL, action string, name string) *url.URL {
func v2AuthURL(ep url.URL, action string, name string) *url.URL {
if name != "" {
ep.Path = path.Join(ep.Path, defaultV2SecurityPrefix, action, name)
ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name)
return &ep
}
ep.Path = path.Join(ep.Path, defaultV2SecurityPrefix, action)
ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action)
return &ep
}
// NewSecurityAPI constructs a new SecurityAPI that uses HTTP to
// interact with etcd's general security features.
func NewSecurityAPI(c Client) SecurityAPI {
return &httpSecurityAPI{
// NewAuthAPI constructs a new AuthAPI that uses HTTP to
// interact with etcd's general auth features.
func NewAuthAPI(c Client) AuthAPI {
return &httpAuthAPI{
client: c,
}
}
type SecurityAPI interface {
// Enable security.
type AuthAPI interface {
// Enable auth.
Enable(ctx context.Context) error
// Disable security.
// Disable auth.
Disable(ctx context.Context) error
}
type httpSecurityAPI struct {
type httpAuthAPI struct {
client httpClient
}
func (s *httpSecurityAPI) Enable(ctx context.Context) error {
return s.enableDisable(ctx, &securityAPIAction{"PUT"})
func (s *httpAuthAPI) Enable(ctx context.Context) error {
return s.enableDisable(ctx, &authAPIAction{"PUT"})
}
func (s *httpSecurityAPI) Disable(ctx context.Context) error {
return s.enableDisable(ctx, &securityAPIAction{"DELETE"})
func (s *httpAuthAPI) Disable(ctx context.Context) error {
return s.enableDisable(ctx, &authAPIAction{"DELETE"})
}
func (s *httpSecurityAPI) enableDisable(ctx context.Context, req httpAction) error {
func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error {
resp, body, err := s.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return err
@ -89,34 +89,34 @@ func (s *httpSecurityAPI) enableDisable(ctx context.Context, req httpAction) err
return nil
}
type securityAPIAction struct {
type authAPIAction struct {
verb string
}
func (l *securityAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2SecurityURL(ep, "enable", "")
func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "enable", "")
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
}
type securityError struct {
type authError struct {
Message string `json:"message"`
Code int `json:"-"`
}
func (e securityError) Error() string {
func (e authError) Error() string {
return e.Message
}
// NewSecurityUserAPI constructs a new SecurityUserAPI that uses HTTP to
// NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to
// interact with etcd's user creation and modification features.
func NewSecurityUserAPI(c Client) SecurityUserAPI {
return &httpSecurityUserAPI{
func NewAuthUserAPI(c Client) AuthUserAPI {
return &httpAuthUserAPI{
client: c,
}
}
type SecurityUserAPI interface {
type AuthUserAPI interface {
// Add a user.
AddUser(ctx context.Context, username string, password string) error
@ -139,27 +139,27 @@ type SecurityUserAPI interface {
ListUsers(ctx context.Context) ([]string, error)
}
type httpSecurityUserAPI struct {
type httpAuthUserAPI struct {
client httpClient
}
type securityUserAPIAction struct {
type authUserAPIAction struct {
verb string
username string
user *User
}
type securityUserAPIList struct{}
type authUserAPIList struct{}
func (list *securityUserAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2SecurityURL(ep, "users", "")
func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "users", "")
req, _ := http.NewRequest("GET", u.String(), nil)
req.Header.Set("Content-Type", "application/json")
return req
}
func (l *securityUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2SecurityURL(ep, "users", l.username)
func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
u := v2AuthURL(ep, "users", l.username)
if l.user == nil {
req, _ := http.NewRequest(l.verb, u.String(), nil)
return req
@ -174,13 +174,13 @@ func (l *securityUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
return req
}
func (u *httpSecurityUserAPI) ListUsers(ctx context.Context) ([]string, error) {
resp, body, err := u.client.Do(ctx, &securityUserAPIList{})
func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) {
resp, body, err := u.client.Do(ctx, &authUserAPIList{})
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return nil, err
@ -197,32 +197,32 @@ func (u *httpSecurityUserAPI) ListUsers(ctx context.Context) ([]string, error) {
return userList.Users, nil
}
func (u *httpSecurityUserAPI) AddUser(ctx context.Context, username string, password string) error {
func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error {
user := &User{
User: username,
Password: password,
}
return u.addRemoveUser(ctx, &securityUserAPIAction{
return u.addRemoveUser(ctx, &authUserAPIAction{
verb: "PUT",
username: username,
user: user,
})
}
func (u *httpSecurityUserAPI) RemoveUser(ctx context.Context, username string) error {
return u.addRemoveUser(ctx, &securityUserAPIAction{
func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username string) error {
return u.addRemoveUser(ctx, &authUserAPIAction{
verb: "DELETE",
username: username,
})
}
func (u *httpSecurityUserAPI) addRemoveUser(ctx context.Context, req *securityUserAPIAction) error {
func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAction) error {
resp, body, err := u.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return err
@ -232,56 +232,56 @@ func (u *httpSecurityUserAPI) addRemoveUser(ctx context.Context, req *securityUs
return nil
}
func (u *httpSecurityUserAPI) GetUser(ctx context.Context, username string) (*User, error) {
return u.modUser(ctx, &securityUserAPIAction{
func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string) (*User, error) {
return u.modUser(ctx, &authUserAPIAction{
verb: "GET",
username: username,
})
}
func (u *httpSecurityUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) {
func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) {
user := &User{
User: username,
Grant: roles,
}
return u.modUser(ctx, &securityUserAPIAction{
return u.modUser(ctx, &authUserAPIAction{
verb: "PUT",
username: username,
user: user,
})
}
func (u *httpSecurityUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) {
func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) {
user := &User{
User: username,
Revoke: roles,
}
return u.modUser(ctx, &securityUserAPIAction{
return u.modUser(ctx, &authUserAPIAction{
verb: "PUT",
username: username,
user: user,
})
}
func (u *httpSecurityUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) {
func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) {
user := &User{
User: username,
Password: password,
}
return u.modUser(ctx, &securityUserAPIAction{
return u.modUser(ctx, &authUserAPIAction{
verb: "PUT",
username: username,
user: user,
})
}
func (u *httpSecurityUserAPI) modUser(ctx context.Context, req *securityUserAPIAction) (*User, error) {
func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) (*User, error) {
resp, body, err := u.client.Do(ctx, req)
if err != nil {
return nil, err
}
if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
var sec securityError
var sec authError
err := json.Unmarshal(body, &sec)
if err != nil {
return nil, err

View File

@ -24,49 +24,49 @@ import (
"github.com/coreos/etcd/client"
)
func NewSecurityCommands() cli.Command {
func NewAuthCommands() cli.Command {
return cli.Command{
Name: "security",
Usage: "overall security controls",
Name: "auth",
Usage: "overall auth controls",
Subcommands: []cli.Command{
cli.Command{
Name: "enable",
Usage: "enable security access controls",
Action: actionSecurityEnable,
Usage: "enable auth access controls",
Action: actionAuthEnable,
},
cli.Command{
Name: "disable",
Usage: "disable security access controls",
Action: actionSecurityDisable,
Usage: "disable auth access controls",
Action: actionAuthDisable,
},
},
}
}
func actionSecurityEnable(c *cli.Context) {
securityEnableDisable(c, true)
func actionAuthEnable(c *cli.Context) {
authEnableDisable(c, true)
}
func actionSecurityDisable(c *cli.Context) {
securityEnableDisable(c, false)
func actionAuthDisable(c *cli.Context) {
authEnableDisable(c, false)
}
func mustNewSecurityAPI(c *cli.Context) client.SecurityAPI {
func mustNewAuthAPI(c *cli.Context) client.AuthAPI {
hc := mustNewClient(c)
if c.GlobalBool("debug") {
fmt.Fprintf(os.Stderr, "Cluster-Endpoints: %s\n", strings.Join(hc.Endpoints(), ", "))
}
return client.NewSecurityAPI(hc)
return client.NewAuthAPI(hc)
}
func securityEnableDisable(c *cli.Context, enable bool) {
func authEnableDisable(c *cli.Context, enable bool) {
if len(c.Args()) != 0 {
fmt.Fprintln(os.Stderr, "No arguments accepted")
os.Exit(1)
}
s := mustNewSecurityAPI(c)
s := mustNewAuthAPI(c)
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
var err error
if enable {
@ -80,8 +80,8 @@ func securityEnableDisable(c *cli.Context, enable bool) {
os.Exit(1)
}
if enable {
fmt.Println("Security Enabled")
fmt.Println("Authentication Enabled")
} else {
fmt.Println("Security Disabled")
fmt.Println("Authentication Disabled")
}
}

View File

@ -76,14 +76,14 @@ func NewRoleCommands() cli.Command {
}
}
func mustNewSecurityRoleAPI(c *cli.Context) client.SecurityRoleAPI {
func mustNewAuthRoleAPI(c *cli.Context) client.AuthRoleAPI {
hc := mustNewClient(c)
if c.GlobalBool("debug") {
fmt.Fprintf(os.Stderr, "Cluster-Endpoints: %s\n", strings.Join(hc.Endpoints(), ", "))
}
return client.NewSecurityRoleAPI(hc)
return client.NewAuthRoleAPI(hc)
}
func actionRoleList(c *cli.Context) {
@ -91,7 +91,7 @@ func actionRoleList(c *cli.Context) {
fmt.Fprintln(os.Stderr, "No arguments accepted")
os.Exit(1)
}
r := mustNewSecurityRoleAPI(c)
r := mustNewAuthRoleAPI(c)
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
roles, err := r.ListRoles(ctx)
cancel()
@ -228,7 +228,7 @@ func actionRoleGet(c *cli.Context) {
}
}
func mustRoleAPIAndName(c *cli.Context) (client.SecurityRoleAPI, string) {
func mustRoleAPIAndName(c *cli.Context) (client.AuthRoleAPI, string) {
args := c.Args()
if len(args) != 1 {
fmt.Fprintln(os.Stderr, "Please provide a role name")
@ -236,6 +236,6 @@ func mustRoleAPIAndName(c *cli.Context) (client.SecurityRoleAPI, string) {
}
name := args[0]
api := mustNewSecurityRoleAPI(c)
api := mustNewAuthRoleAPI(c)
return api, name
}

View File

@ -73,14 +73,14 @@ func NewUserCommands() cli.Command {
}
}
func mustNewSecurityUserAPI(c *cli.Context) client.SecurityUserAPI {
func mustNewAuthUserAPI(c *cli.Context) client.AuthUserAPI {
hc := mustNewClient(c)
if c.GlobalBool("debug") {
fmt.Fprintf(os.Stderr, "Cluster-Endpoints: %s\n", strings.Join(hc.Endpoints(), ", "))
}
return client.NewSecurityUserAPI(hc)
return client.NewAuthUserAPI(hc)
}
func actionUserList(c *cli.Context) {
@ -88,7 +88,7 @@ func actionUserList(c *cli.Context) {
fmt.Fprintln(os.Stderr, "No arguments accepted")
os.Exit(1)
}
u := mustNewSecurityUserAPI(c)
u := mustNewAuthUserAPI(c)
ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
users, err := u.ListUsers(ctx)
cancel()
@ -229,14 +229,14 @@ func actionUserGet(c *cli.Context) {
}
func mustUserAPIAndName(c *cli.Context) (client.SecurityUserAPI, string) {
func mustUserAPIAndName(c *cli.Context) (client.AuthUserAPI, string) {
args := c.Args()
if len(args) != 1 {
fmt.Fprintln(os.Stderr, "Please provide a username")
os.Exit(1)
}
api := mustNewSecurityUserAPI(c)
api := mustNewAuthUserAPI(c)
username := args[0]
return api, username
}

View File

@ -56,7 +56,7 @@ func main() {
command.NewImportSnapCommand(),
command.NewUserCommands(),
command.NewRoleCommands(),
command.NewSecurityCommands(),
command.NewAuthCommands(),
}
app.Run(os.Args)

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package security
package auth
import (
"encoding/json"
@ -44,7 +44,7 @@ const (
)
var (
plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "security")
plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "auth")
)
var rootRole = Role{
@ -108,11 +108,11 @@ type Error struct {
func (se Error) Error() string { return se.errmsg }
func mergeErr(s string, v ...interface{}) Error {
return Error{fmt.Sprintf("security: "+s, v...)}
return Error{fmt.Sprintf("auth: "+s, v...)}
}
func securityErr(s string, v ...interface{}) Error {
return Error{fmt.Sprintf("security: "+s, v...)}
func authErr(s string, v ...interface{}) Error {
return Error{fmt.Sprintf("auth: "+s, v...)}
}
func NewStore(server doer, timeout time.Duration) *Store {
@ -147,7 +147,7 @@ func (s *Store) GetUser(name string) (User, error) {
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return User{}, securityErr("User %s does not exist.", name)
return User{}, authErr("User %s does not exist.", name)
}
}
return User{}, err
@ -197,7 +197,7 @@ func (s *Store) CreateUser(user User) (User, error) {
func (s *Store) createUserInternal(user User) (User, error) {
if user.Password == "" {
return user, securityErr("Cannot create user %s with an empty password", user.User)
return user, authErr("Cannot create user %s with an empty password", user.User)
}
hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
if err != nil {
@ -209,7 +209,7 @@ func (s *Store) createUserInternal(user User) (User, error) {
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeNodeExist {
return user, securityErr("User %s already exists.", user.User)
return user, authErr("User %s already exists.", user.User)
}
}
}
@ -217,14 +217,14 @@ func (s *Store) createUserInternal(user User) (User, error) {
}
func (s *Store) DeleteUser(name string) error {
if s.SecurityEnabled() && name == "root" {
return securityErr("Cannot delete root user while security is enabled.")
if s.AuthEnabled() && name == "root" {
return authErr("Cannot delete root user while auth is enabled.")
}
_, err := s.deleteResource("/users/" + name)
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return securityErr("User %s does not exist", name)
return authErr("User %s does not exist", name)
}
}
return err
@ -238,7 +238,7 @@ func (s *Store) UpdateUser(user User) (User, error) {
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return user, securityErr("User %s doesn't exist.", user.User)
return user, authErr("User %s doesn't exist.", user.User)
}
}
return old, err
@ -249,9 +249,9 @@ func (s *Store) UpdateUser(user User) (User, error) {
}
if reflect.DeepEqual(old, newUser) {
if user.Revoke != nil || user.Grant != nil {
return old, securityErr("User not updated. Grant/Revoke lists didn't match any current roles.")
return old, authErr("User not updated. Grant/Revoke lists didn't match any current roles.")
}
return old, securityErr("User not updated. Use Grant/Revoke/Password to update the user.")
return old, authErr("User not updated. Use Grant/Revoke/Password to update the user.")
}
_, err = s.updateResource("/users/"+user.User, newUser)
if err == nil {
@ -287,7 +287,7 @@ func (s *Store) GetRole(name string) (Role, error) {
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return Role{}, securityErr("Role %s does not exist.", name)
return Role{}, authErr("Role %s does not exist.", name)
}
}
return Role{}, err
@ -313,13 +313,13 @@ func (s *Store) CreateOrUpdateRole(r Role) (role Role, created bool, err error)
func (s *Store) CreateRole(role Role) error {
if role.Role == RootRoleName {
return securityErr("Cannot modify role %s: is root role.", role.Role)
return authErr("Cannot modify role %s: is root role.", role.Role)
}
_, err := s.createResource("/roles/"+role.Role, role)
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeNodeExist {
return securityErr("Role %s already exists.", role.Role)
return authErr("Role %s already exists.", role.Role)
}
}
}
@ -331,13 +331,13 @@ func (s *Store) CreateRole(role Role) error {
func (s *Store) DeleteRole(name string) error {
if name == RootRoleName {
return securityErr("Cannot modify role %s: is superuser role.", name)
return authErr("Cannot modify role %s: is superuser role.", name)
}
_, err := s.deleteResource("/roles/" + name)
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return securityErr("Role %s doesn't exist.", name)
return authErr("Role %s doesn't exist.", name)
}
}
}
@ -352,7 +352,7 @@ func (s *Store) UpdateRole(role Role) (Role, error) {
if err != nil {
if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound {
return role, securityErr("Role %s doesn't exist.", role.Role)
return role, authErr("Role %s doesn't exist.", role.Role)
}
}
return old, err
@ -363,9 +363,9 @@ func (s *Store) UpdateRole(role Role) (Role, error) {
}
if reflect.DeepEqual(old, newRole) {
if role.Revoke != nil || role.Grant != nil {
return old, securityErr("Role not updated. Grant/Revoke lists didn't match any current permissions.")
return old, authErr("Role not updated. Grant/Revoke lists didn't match any current permissions.")
}
return old, securityErr("Role not updated. Use Grant/Revoke to update the role.")
return old, authErr("Role not updated. Use Grant/Revoke to update the role.")
}
_, err = s.updateResource("/roles/"+role.Role, newRole)
if err == nil {
@ -374,45 +374,45 @@ func (s *Store) UpdateRole(role Role) (Role, error) {
return newRole, err
}
func (s *Store) SecurityEnabled() bool {
return s.detectSecurity()
func (s *Store) AuthEnabled() bool {
return s.detectAuth()
}
func (s *Store) EnableSecurity() error {
if s.SecurityEnabled() {
return securityErr("already enabled")
func (s *Store) EnableAuth() error {
if s.AuthEnabled() {
return authErr("already enabled")
}
_, err := s.GetUser("root")
if err != nil {
return securityErr("No root user available, please create one")
return authErr("No root user available, please create one")
}
_, err = s.GetRole(GuestRoleName)
if err != nil {
plog.Printf("no guest role access found, creating default")
err := s.CreateRole(guestRole)
if err != nil {
plog.Errorf("error creating guest role. aborting security enable.")
plog.Errorf("error creating guest role. aborting auth enable.")
return err
}
}
err = s.enableSecurity()
err = s.enableAuth()
if err == nil {
plog.Noticef("security: enabled security")
plog.Noticef("auth: enabled auth")
} else {
plog.Errorf("error enabling security (%v)", err)
plog.Errorf("error enabling auth (%v)", err)
}
return err
}
func (s *Store) DisableSecurity() error {
if !s.SecurityEnabled() {
return securityErr("already disabled")
func (s *Store) DisableAuth() error {
if !s.AuthEnabled() {
return authErr("already disabled")
}
err := s.disableSecurity()
err := s.disableAuth()
if err == nil {
plog.Noticef("security: disabled security")
plog.Noticef("auth: disabled auth")
} else {
plog.Errorf("error disabling security (%v)", err)
plog.Errorf("error disabling auth (%v)", err)
}
return err
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package security
package auth
import (
"encoding/json"
@ -24,7 +24,7 @@ import (
"github.com/coreos/etcd/etcdserver/etcdserverpb"
)
func (s *Store) ensureSecurityDirectories() error {
func (s *Store) ensureAuthDirectories() error {
if s.ensuredOnce {
return nil
}
@ -45,7 +45,7 @@ func (s *Store) ensureSecurityDirectories() error {
continue
}
}
plog.Errorf("failed to create security directories in the store (%v)", err)
plog.Errorf("failed to create auth directories in the store (%v)", err)
return err
}
}
@ -72,16 +72,16 @@ func (s *Store) ensureSecurityDirectories() error {
return nil
}
func (s *Store) enableSecurity() error {
func (s *Store) enableAuth() error {
_, err := s.updateResource("/enabled", true)
return err
}
func (s *Store) disableSecurity() error {
func (s *Store) disableAuth() error {
_, err := s.updateResource("/enabled", false)
return err
}
func (s *Store) detectSecurity() bool {
func (s *Store) detectAuth() bool {
if s.server == nil {
return false
}
@ -92,7 +92,7 @@ func (s *Store) detectSecurity() bool {
return false
}
}
plog.Errorf("failed to detect security settings (%s)", err)
plog.Errorf("failed to detect auth settings (%s)", err)
return false
}
@ -124,7 +124,7 @@ func (s *Store) createResource(res string, value interface{}) (etcdserver.Respon
return s.setResource(res, value, false)
}
func (s *Store) setResource(res string, value interface{}, prevexist bool) (etcdserver.Response, error) {
err := s.ensureSecurityDirectories()
err := s.ensureAuthDirectories()
if err != nil {
return etcdserver.Response{}, err
}
@ -145,7 +145,7 @@ func (s *Store) setResource(res string, value interface{}, prevexist bool) (etcd
}
func (s *Store) deleteResource(res string) (etcdserver.Response, error) {
err := s.ensureSecurityDirectories()
err := s.ensureAuthDirectories()
if err != nil {
return etcdserver.Response{}, err
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package security
package auth
import (
"reflect"

View File

@ -14,14 +14,14 @@ import (
type capability string
const (
securityCapability capability = "security"
authCapability capability = "auth"
)
var (
// capabilityMap is a static map of version to capability map.
// the base capabilities is the set of capability 2.0 supports.
capabilityMaps = map[string]map[capability]bool{
"2.1.0": {securityCapability: true},
"2.1.0": {authCapability: true},
}
enableMapMu sync.Mutex

View File

@ -32,9 +32,9 @@ import (
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
etcdErr "github.com/coreos/etcd/error"
"github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/auth"
"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
"github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/etcdserver/security"
"github.com/coreos/etcd/etcdserver/stats"
"github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/raft"
@ -43,7 +43,7 @@ import (
)
const (
securityPrefix = "/v2/security"
authPrefix = "/v2/auth"
keysPrefix = "/v2/keys"
deprecatedMachinesPrefix = "/v2/machines"
membersPrefix = "/v2/members"
@ -58,7 +58,7 @@ const (
func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
go capabilityLoop(server)
sec := security.NewStore(server, defaultServerTimeout)
sec := auth.NewStore(server, defaultServerTimeout)
kh := &keysHandler{
sec: sec,
@ -83,7 +83,7 @@ func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
cluster: server.Cluster(),
}
sech := &securityHandler{
sech := &authHandler{
sec: sec,
cluster: server.Cluster(),
}
@ -102,13 +102,13 @@ func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
mux.Handle(membersPrefix, mh)
mux.Handle(membersPrefix+"/", mh)
mux.Handle(deprecatedMachinesPrefix, dmh)
handleSecurity(mux, sech)
handleAuth(mux, sech)
return requestLogger(mux)
}
type keysHandler struct {
sec *security.Store
sec *auth.Store
server etcdserver.Server
cluster etcdserver.Cluster
timer etcdserver.RaftTimer
@ -170,7 +170,7 @@ func (h *deprecatedMachinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
}
type membersHandler struct {
sec *security.Store
sec *auth.Store
server etcdserver.Server
cluster etcdserver.Cluster
clock clockwork.Clock

View File

@ -21,29 +21,29 @@ import (
"strings"
"github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/auth"
"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
"github.com/coreos/etcd/etcdserver/security"
"github.com/coreos/etcd/pkg/netutil"
)
type securityHandler struct {
sec *security.Store
type authHandler struct {
sec *auth.Store
cluster etcdserver.Cluster
}
func hasWriteRootAccess(sec *security.Store, r *http.Request) bool {
func hasWriteRootAccess(sec *auth.Store, r *http.Request) bool {
if r.Method == "GET" || r.Method == "HEAD" {
return true
}
return hasRootAccess(sec, r)
}
func hasRootAccess(sec *security.Store, r *http.Request) bool {
func hasRootAccess(sec *auth.Store, r *http.Request) bool {
if sec == nil {
// No store means no security available, eg, tests.
// No store means no auth available, eg, tests.
return true
}
if !sec.SecurityEnabled() {
if !sec.AuthEnabled() {
return true
}
username, password, ok := netutil.BasicAuth(r)
@ -56,24 +56,24 @@ func hasRootAccess(sec *security.Store, r *http.Request) bool {
}
ok = rootUser.CheckPassword(password)
if !ok {
plog.Warningf("security: wrong password for user %s", username)
plog.Warningf("auth: wrong password for user %s", username)
return false
}
for _, role := range rootUser.Roles {
if role == security.RootRoleName {
if role == auth.RootRoleName {
return true
}
}
plog.Warningf("security: user %s does not have the %s role for resource %s.", username, security.RootRoleName, r.URL.Path)
plog.Warningf("auth: user %s does not have the %s role for resource %s.", username, auth.RootRoleName, r.URL.Path)
return false
}
func hasKeyPrefixAccess(sec *security.Store, r *http.Request, key string, recursive bool) bool {
func hasKeyPrefixAccess(sec *auth.Store, r *http.Request, key string, recursive bool) bool {
if sec == nil {
// No store means no security available, eg, tests.
// No store means no auth available, eg, tests.
return true
}
if !sec.SecurityEnabled() {
if !sec.AuthEnabled() {
return true
}
username, password, ok := netutil.BasicAuth(r)
@ -82,12 +82,12 @@ func hasKeyPrefixAccess(sec *security.Store, r *http.Request, key string, recurs
}
user, err := sec.GetUser(username)
if err != nil {
plog.Warningf("security: no such user: %s.", username)
plog.Warningf("auth: no such user: %s.", username)
return false
}
authAsUser := user.CheckPassword(password)
if !authAsUser {
plog.Warningf("security: incorrect password for user: %s.", username)
plog.Warningf("auth: incorrect password for user: %s.", username)
return false
}
writeAccess := r.Method != "GET" && r.Method != "HEAD"
@ -101,20 +101,20 @@ func hasKeyPrefixAccess(sec *security.Store, r *http.Request, key string, recurs
}
return role.HasKeyAccess(key, writeAccess)
}
plog.Warningf("security: invalid access for user %s on key %s.", username, key)
plog.Warningf("auth: invalid access for user %s on key %s.", username, key)
return false
}
func hasGuestAccess(sec *security.Store, r *http.Request, key string) bool {
func hasGuestAccess(sec *auth.Store, r *http.Request, key string) bool {
writeAccess := r.Method != "GET" && r.Method != "HEAD"
role, err := sec.GetRole(security.GuestRoleName)
role, err := sec.GetRole(auth.GuestRoleName)
if err != nil {
return false
}
if role.HasKeyAccess(key, writeAccess) {
return true
}
plog.Warningf("security: invalid access for unauthenticated user on resource %s.", key)
plog.Warningf("auth: invalid access for unauthenticated user on resource %s.", key)
return false
}
@ -123,15 +123,15 @@ func writeNoAuth(w http.ResponseWriter) {
herr.WriteTo(w)
}
func handleSecurity(mux *http.ServeMux, sh *securityHandler) {
mux.HandleFunc(securityPrefix+"/roles", capabilityHandler(securityCapability, sh.baseRoles))
mux.HandleFunc(securityPrefix+"/roles/", capabilityHandler(securityCapability, sh.handleRoles))
mux.HandleFunc(securityPrefix+"/users", capabilityHandler(securityCapability, sh.baseUsers))
mux.HandleFunc(securityPrefix+"/users/", capabilityHandler(securityCapability, sh.handleUsers))
mux.HandleFunc(securityPrefix+"/enable", capabilityHandler(securityCapability, sh.enableDisable))
func handleAuth(mux *http.ServeMux, sh *authHandler) {
mux.HandleFunc(authPrefix+"/roles", capabilityHandler(authCapability, sh.baseRoles))
mux.HandleFunc(authPrefix+"/roles/", capabilityHandler(authCapability, sh.handleRoles))
mux.HandleFunc(authPrefix+"/users", capabilityHandler(authCapability, sh.baseUsers))
mux.HandleFunc(authPrefix+"/users/", capabilityHandler(authCapability, sh.handleUsers))
mux.HandleFunc(authPrefix+"/enable", capabilityHandler(authCapability, sh.enableDisable))
}
func (sh *securityHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
if !allowMethod(w, r.Method, "GET") {
return
}
@ -160,8 +160,8 @@ func (sh *securityHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
}
}
func (sh *securityHandler) handleRoles(w http.ResponseWriter, r *http.Request) {
subpath := path.Clean(r.URL.Path[len(securityPrefix):])
func (sh *authHandler) handleRoles(w http.ResponseWriter, r *http.Request) {
subpath := path.Clean(r.URL.Path[len(authPrefix):])
// Split "/roles/rolename/command".
// First item is an empty string, second is "roles"
pieces := strings.Split(subpath, "/")
@ -176,7 +176,7 @@ func (sh *securityHandler) handleRoles(w http.ResponseWriter, r *http.Request) {
sh.forRole(w, r, pieces[2])
}
func (sh *securityHandler) forRole(w http.ResponseWriter, r *http.Request, role string) {
func (sh *authHandler) forRole(w http.ResponseWriter, r *http.Request, role string) {
if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
return
}
@ -201,7 +201,7 @@ func (sh *securityHandler) forRole(w http.ResponseWriter, r *http.Request, role
}
return
case "PUT":
var in security.Role
var in auth.Role
err := json.NewDecoder(r.Body).Decode(&in)
if err != nil {
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
@ -236,7 +236,7 @@ func (sh *securityHandler) forRole(w http.ResponseWriter, r *http.Request, role
}
}
func (sh *securityHandler) baseUsers(w http.ResponseWriter, r *http.Request) {
func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) {
if !allowMethod(w, r.Method, "GET") {
return
}
@ -265,8 +265,8 @@ func (sh *securityHandler) baseUsers(w http.ResponseWriter, r *http.Request) {
}
}
func (sh *securityHandler) handleUsers(w http.ResponseWriter, r *http.Request) {
subpath := path.Clean(r.URL.Path[len(securityPrefix):])
func (sh *authHandler) handleUsers(w http.ResponseWriter, r *http.Request) {
subpath := path.Clean(r.URL.Path[len(authPrefix):])
// Split "/users/username".
// First item is an empty string, second is "users"
pieces := strings.Split(subpath, "/")
@ -281,7 +281,7 @@ func (sh *securityHandler) handleUsers(w http.ResponseWriter, r *http.Request) {
sh.forUser(w, r, pieces[2])
}
func (sh *securityHandler) forUser(w http.ResponseWriter, r *http.Request, user string) {
func (sh *authHandler) forUser(w http.ResponseWriter, r *http.Request, user string) {
if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
return
}
@ -308,7 +308,7 @@ func (sh *securityHandler) forUser(w http.ResponseWriter, r *http.Request, user
}
return
case "PUT":
var u security.User
var u auth.User
err := json.NewDecoder(r.Body).Decode(&u)
if err != nil {
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
@ -351,7 +351,7 @@ type enabled struct {
Enabled bool `json:"enabled"`
}
func (sh *securityHandler) enableDisable(w http.ResponseWriter, r *http.Request) {
func (sh *authHandler) enableDisable(w http.ResponseWriter, r *http.Request) {
if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
return
}
@ -361,22 +361,22 @@ func (sh *securityHandler) enableDisable(w http.ResponseWriter, r *http.Request)
}
w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
w.Header().Set("Content-Type", "application/json")
isEnabled := sh.sec.SecurityEnabled()
isEnabled := sh.sec.AuthEnabled()
switch r.Method {
case "GET":
jsonDict := enabled{isEnabled}
err := json.NewEncoder(w).Encode(jsonDict)
if err != nil {
plog.Warningf("error encoding security state on %s", r.URL)
plog.Warningf("error encoding auth state on %s", r.URL)
}
case "PUT":
err := sh.sec.EnableSecurity()
err := sh.sec.EnableAuth()
if err != nil {
writeError(w, err)
return
}
case "DELETE":
err := sh.sec.DisableSecurity()
err := sh.sec.DisableAuth()
if err != nil {
writeError(w, err)
return

View File

@ -23,8 +23,8 @@ import (
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
etcdErr "github.com/coreos/etcd/error"
"github.com/coreos/etcd/etcdserver/auth"
"github.com/coreos/etcd/etcdserver/etcdhttp/httptypes"
"github.com/coreos/etcd/etcdserver/security"
)
const (
@ -55,7 +55,7 @@ func writeError(w http.ResponseWriter, err error) {
e.WriteTo(w)
case *httptypes.HTTPError:
e.WriteTo(w)
case security.Error:
case auth.Error:
herr := httptypes.NewHTTPError(http.StatusBadRequest, e.Error())
herr.WriteTo(w)
default: