Skip to content

Commit

Permalink
Merge pull request #3373 from hashicorp/f-403
Browse files Browse the repository at this point in the history
Permission denied results in 403
  • Loading branch information
dadgar authored Oct 12, 2017
2 parents 918f475 + f1965d6 commit be053a4
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 0 deletions.
15 changes: 15 additions & 0 deletions command/agent/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func (c *Command) readConfig() *Config {
Ports: &Ports{},
Server: &ServerConfig{},
Vault: &config.VaultConfig{},
ACL: &ACLConfig{},
}

flags := flag.NewFlagSet("agent", flag.ContinueOnError)
Expand Down Expand Up @@ -166,6 +167,10 @@ func (c *Command) readConfig() *Config {
}), "vault-tls-skip-verify", "")
flags.StringVar(&cmdConfig.Vault.TLSServerName, "vault-tls-server-name", "", "")

// ACL options
flags.BoolVar(&cmdConfig.ACL.Enabled, "acl-enabled", false, "")
flags.StringVar(&cmdConfig.ACL.ReplicationToken, "acl-replication-token", "", "")

if err := flags.Parse(c.args); err != nil {
return nil
}
Expand Down Expand Up @@ -984,6 +989,16 @@ Client Options:
The default speed for network interfaces in MBits if the link speed can not
be determined dynamically.
ACL Options:
-acl-enabled
Specifies whether the agent should enable ACLs.
-acl-replication-token
The replication token for servers to use when replicating from the
authoratative region. The token must be a valid management token from the
authoratative region.
Consul Options:
-consul-address=<addr>
Expand Down
6 changes: 6 additions & 0 deletions command/agent/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,13 @@ func (s *HTTPServer) wrap(handler func(resp http.ResponseWriter, req *http.Reque
code := 500
if http, ok := err.(HTTPCodedError); ok {
code = http.Code()
} else {
switch err.Error() {
case structs.ErrPermissionDenied.Error(), structs.ErrTokenNotFound.Error():
code = 403
}
}

resp.WriteHeader(code)
resp.Write([]byte(err.Error()))
return
Expand Down
35 changes: 35 additions & 0 deletions command/agent/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/nomad/structs/config"
"github.com/hashicorp/nomad/testutil"
"github.com/stretchr/testify/assert"
"github.com/ugorji/go/codec"
)

Expand Down Expand Up @@ -218,6 +219,40 @@ func testPrettyPrint(pretty string, prettyFmt bool, t *testing.T) {
}
}

func TestPermissionDenied(t *testing.T) {
s := makeHTTPServer(t, func(c *Config) {
c.ACL.Enabled = true
})
defer s.Shutdown()

resp := httptest.NewRecorder()
handler := func(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
return nil, structs.ErrPermissionDenied
}

urlStr := "/v1/job/foo"
req, _ := http.NewRequest("GET", urlStr, nil)
s.Server.wrap(handler)(resp, req)
assert.Equal(t, resp.Code, 403)
}

func TestTokenNotFound(t *testing.T) {
s := makeHTTPServer(t, func(c *Config) {
c.ACL.Enabled = true
})
defer s.Shutdown()

resp := httptest.NewRecorder()
handler := func(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
return nil, structs.ErrTokenNotFound
}

urlStr := "/v1/job/foo"
req, _ := http.NewRequest("GET", urlStr, nil)
s.Server.wrap(handler)(resp, req)
assert.Equal(t, resp.Code, 403)
}

func TestParseWait(t *testing.T) {
t.Parallel()
resp := httptest.NewRecorder()
Expand Down
31 changes: 31 additions & 0 deletions command/agent/job_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,37 @@ func TestHTTP_JobsRegister_ACL(t *testing.T) {
})
}

// Test that permission denied gets a 403
func TestHTTP_JobsRegister_ACL_Bad(t *testing.T) {
t.Parallel()
httpACLTest(t, nil, func(s *TestAgent) {
// Create the job
job := api.MockJob()
args := api.JobRegisterRequest{
Job: job,
WriteRequest: api.WriteRequest{
Region: "global",
},
}
buf := encodeReq(args)

// Make the HTTP request
req, err := http.NewRequest("PUT", "/v1/jobs", buf)
if err != nil {
t.Fatalf("err: %v", err)
}
respW := httptest.NewRecorder()

// Make the request
obj, err := s.Server.JobsRequest(respW, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(t, obj)
assert.Contains(t, err.Error(), "403")
})
}

func TestHTTP_JobsRegister_Defaulting(t *testing.T) {
t.Parallel()
httpTest(t, nil, func(s *TestAgent) {
Expand Down
2 changes: 2 additions & 0 deletions website/source/docs/commands/agent.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ via CLI arguments. The `agent` command accepts the following arguments:

* `-alloc-dir=<path>`: Equivalent to the Client [alloc_dir](#alloc_dir) config
option.
* `-acl-enabled`: Equivalent to the ACL [enabled](/docs/agent/configuration/acl.html#enabled) config option.
* `-acl-replication-token`: Equivalent to the ACL [replication_token](/docs/agent/configuration/acl.html#replication_token) config option.
* `-bind=<address>`: Equivalent to the [bind_addr](#bind_addr) config option.
* `-bootstrap-expect=<num>`: Equivalent to the
[bootstrap_expect](#bootstrap_expect) config option.
Expand Down

0 comments on commit be053a4

Please sign in to comment.