Skip to content

Commit 03377df

Browse files
committed
Added initial jwt-secret support
1 parent 28311d9 commit 03377df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3604
-14
lines changed

main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"fmt"
6+
"io/ioutil"
67
"os"
78
"os/signal"
89
"path/filepath"
@@ -47,6 +48,7 @@ var (
4748
verbose bool
4849
serverThreads int
4950
allPortOffsetsUnique bool
51+
jwtSecretFile string
5052
dockerEndpoint string
5153
dockerImage string
5254
dockerUser string
@@ -79,6 +81,7 @@ func init() {
7981
f.BoolVar(&dockerNetHost, "dockerNetHost", false, "Run containers with --net=host")
8082
f.BoolVar(&dockerPrivileged, "dockerPrivileged", false, "Run containers with --privileged")
8183
f.BoolVar(&allPortOffsetsUnique, "uniquePortOffsets", false, "If set, all peers will get a unique port offset. If false (default) only portOffset+peerAddress pairs will be unique.")
84+
f.StringVar(&jwtSecretFile, "jwtSecretFile", "", "name of a plain text file containing a JWT secret used for server authentication")
8285
}
8386

8487
// handleSignal listens for termination signals and stops this process onup termination.
@@ -191,6 +194,16 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
191194
log.Fatalf("Cannot create data directory %s because %v, giving up.", dataDir, err)
192195
}
193196

197+
// Read jwtSecret (if any)
198+
var jwtSecret string
199+
if jwtSecretFile != "" {
200+
content, err := ioutil.ReadFile(jwtSecretFile)
201+
if err != nil {
202+
log.Fatalf("Failed to read JWT secret file '%s': %v", jwtSecretFile, err)
203+
}
204+
jwtSecret = strings.TrimSpace(string(content))
205+
}
206+
194207
// Interrupt signal:
195208
sigChannel := make(chan os.Signal)
196209
rootCtx, cancel := context.WithCancel(context.Background())
@@ -213,6 +226,7 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
213226
Verbose: verbose,
214227
ServerThreads: serverThreads,
215228
AllPortOffsetsUnique: allPortOffsetsUnique,
229+
JwtSecret: jwtSecret,
216230
RunningInDocker: os.Getenv("RUNNING_IN_DOCKER") == "true",
217231
DockerContainer: dockerContainer,
218232
DockerEndpoint: dockerEndpoint,

service/arangodb.go

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type ServiceConfig struct {
3434
Verbose bool
3535
ServerThreads int // If set to something other than 0, this will be added to the commandline of each server with `--server.threads`...
3636
AllPortOffsetsUnique bool // If set, all peers will get a unique port offset. If false (default) only portOffset+peerAddress pairs will be unique.
37+
JwtSecret string
3738

3839
DockerContainer string // Name of the container running this process
3940
DockerEndpoint string // Where to reach the docker daemon
@@ -136,14 +137,32 @@ func slasher(s string) string {
136137
return strings.Replace(s, "\\", "/", -1)
137138
}
138139

139-
func testInstance(ctx context.Context, address string, port int) (up, cancelled bool) {
140+
func (s *Service) testInstance(ctx context.Context, address string, port int) (up, cancelled bool) {
140141
instanceUp := make(chan bool)
141142
go func() {
142143
client := &http.Client{Timeout: time.Second * 10}
143-
for i := 0; i < 300; i++ {
144+
145+
makeRequest := func() error {
144146
url := fmt.Sprintf("http://%s:%d/_api/version", address, port)
145-
r, e := client.Get(url)
146-
if e == nil && r != nil && r.StatusCode == 200 {
147+
req, err := http.NewRequest("GET", url, nil)
148+
if err != nil {
149+
return maskAny(err)
150+
}
151+
if err := addJwtHeader(req, s.JwtSecret); err != nil {
152+
return maskAny(err)
153+
}
154+
resp, err := client.Do(req)
155+
if err != nil {
156+
return maskAny(err)
157+
}
158+
if resp.StatusCode != 200 {
159+
return maskAny(fmt.Errorf("Invalid status %d", resp.StatusCode))
160+
}
161+
return nil
162+
}
163+
164+
for i := 0; i < 300; i++ {
165+
if err := makeRequest(); err == nil {
147166
instanceUp <- true
148167
break
149168
}
@@ -204,15 +223,20 @@ func (s *Service) makeBaseArgs(myHostDir, myContainerDir string, myAddress strin
204223
threads = "16"
205224
v8Contexts = "4"
206225
}
207-
config := configFile{
208-
&configSection{
209-
Name: "server",
210-
Settings: map[string]string{
211-
"endpoint": fmt.Sprintf("tcp://0.0.0.0:%s", myPort),
212-
"threads": threads,
213-
"authentication": "false",
214-
},
226+
serverSection := &configSection{
227+
Name: "server",
228+
Settings: map[string]string{
229+
"endpoint": fmt.Sprintf("tcp://0.0.0.0:%s", myPort),
230+
"threads": threads,
231+
"authentication": "false",
215232
},
233+
}
234+
if s.JwtSecret != "" {
235+
serverSection.Settings["authentication"] = "true"
236+
serverSection.Settings["jwt-secret"] = s.JwtSecret
237+
}
238+
config := configFile{
239+
serverSection,
216240
&configSection{
217241
Name: "log",
218242
Settings: map[string]string{
@@ -226,6 +250,7 @@ func (s *Service) makeBaseArgs(myHostDir, myContainerDir string, myAddress strin
226250
},
227251
},
228252
}
253+
229254
out, e := os.Create(hostConfFileName)
230255
if e != nil {
231256
s.log.Fatalf("Could not create configuration file %s, error: %#v", hostConfFileName, e)
@@ -354,7 +379,7 @@ func (s *Service) startRunning(runner Runner) {
354379
if p != nil {
355380
s.log.Infof("%s seems to be running already, checking port %d...", mode, myPort)
356381
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
357-
up, _ := testInstance(ctx, myHost, myPort)
382+
up, _ := s.testInstance(ctx, myHost, myPort)
358383
cancel()
359384
if up {
360385
s.log.Infof("%s is already running on %d. No need to start anything.", mode, myPort)
@@ -395,7 +420,7 @@ func (s *Service) startRunning(runner Runner) {
395420
*processVar = p
396421
ctx, cancel := context.WithCancel(s.ctx)
397422
go func() {
398-
if up, cancelled := testInstance(ctx, myHost, s.MasterPort+portOffset+serverPortOffset); !cancelled {
423+
if up, cancelled := s.testInstance(ctx, myHost, s.MasterPort+portOffset+serverPortOffset); !cancelled {
399424
if up {
400425
s.log.Infof("%s up and running.", mode)
401426
} else {

service/jwt.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package service
2+
3+
import (
4+
"net/http"
5+
6+
jwt "github.com/dgrijalva/jwt-go"
7+
)
8+
9+
// addJwtHeader calculates a JWT authorization header based on the given secret
10+
// and adds it to the given request.
11+
// If the secret is empty, nothing is done.
12+
func addJwtHeader(req *http.Request, jwtSecret string) error {
13+
if jwtSecret == "" {
14+
return nil
15+
}
16+
// Create a new token object, specifying signing method and the claims
17+
// you would like it to contain.
18+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
19+
"iss": "arangodb",
20+
"server_id": "foo",
21+
})
22+
23+
// Sign and get the complete encoded token as a string using the secret
24+
signedToken, err := token.SignedString([]byte(jwtSecret))
25+
if err != nil {
26+
return maskAny(err)
27+
}
28+
29+
req.Header.Set("Authorization", "bearer "+signedToken)
30+
return nil
31+
}

vendor/github.com/dgrijalva/jwt-go/.gitignore

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/dgrijalva/jwt-go/.travis.yml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/dgrijalva/jwt-go/LICENSE

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/dgrijalva/jwt-go/README.md

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)