-
Notifications
You must be signed in to change notification settings - Fork 378
/
token.go
103 lines (90 loc) · 2.9 KB
/
token.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"context"
"encoding/base64"
"flag"
"fmt"
"net/http"
"strings"
"github.com/peterbourgon/ff/v3/ffcli"
"golang.org/x/crypto/ed25519"
"berty.tech/berty/v2/go/pkg/bertyprotocol"
)
// This server is a showcase of a PKCE OAuth 2 token issuer. Its behavior is to
// generate a random identifier and sign it, thus allowing a no storage service
// operation. The actual token contains a random identifier and the list of
// services granted by the user, this value is encrypted an not accessible to
// end users. The value returned to the app also contains a map of the services
// endpoints indexed by their identifiers.
//
// For example the JSON response for /oauth/token can include:
// {
// "access_token":
// "a_token",
// "token_type":
// "bearer",
// "scope":
// "replication,contacts,backup",
// "services": {
// "replication": "host:1234",
// "contacts": "host:5678",
// "backup": "other_host:1337"
// }
// }
//
// Where a_token will follow this construction:
// sig(sk, crypt(secret, (uuid, "replication,contacts,backup"])))
//
func tokenServerCommand() *ffcli.Command {
var (
fs = flag.NewFlagSet("token issuer server", flag.ExitOnError)
secretFlag = ""
authSKFlag = ""
listenerFlag = "8080"
supportedFlag = ""
)
fs.StringVar(&secretFlag, "secret", secretFlag, "base64 encoded secret")
fs.StringVar(&authSKFlag, "sk", authSKFlag, "base64 encoded signature key")
fs.StringVar(&listenerFlag, "l", listenerFlag, "http listener")
fs.StringVar(&supportedFlag, "s", supportedFlag, "comma separated list of supported services as name@ip:port")
return &ffcli.Command{
Name: "token-server",
ShortUsage: "berty [global flags] token-server [flags]",
ShortHelp: "token server, a basic token server issuer without auth or logging",
FlagSet: fs,
Exec: func(ctx context.Context, args []string) error {
logger, err := manager.GetLogger()
if err != nil {
return err
}
secret, err := base64.RawStdEncoding.DecodeString(secretFlag)
if err != nil {
return err
}
skBytes, err := base64.RawStdEncoding.DecodeString(authSKFlag)
if err != nil {
return err
}
if len(skBytes) != ed25519.SeedSize {
return fmt.Errorf("invalid sk size")
}
sk := ed25519.NewKeyFromSeed(skBytes)
servicesStrings := strings.Split(supportedFlag, ",")
services := map[string]string{}
for _, s := range servicesStrings {
values := strings.Split(s, "@")
if len(values) != 2 {
return fmt.Errorf("malformed service name: %s", s)
}
services[values[0]] = values[1]
}
server, err := bertyprotocol.NewAuthTokenServer(secret, sk, services, logger)
if err != nil {
return err
}
pk := sk.Public().(ed25519.PublicKey)
logger.Info(fmt.Sprintf("running server, corresponding pk is %s", base64.RawStdEncoding.EncodeToString(pk)))
return http.ListenAndServe(listenerFlag, server)
},
}
}