/
creds.go
96 lines (83 loc) · 2.54 KB
/
creds.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
package auth
import (
"encoding/base64"
"fmt"
"strings"
"golang.org/x/net/context"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)
type security int
const (
public security = iota
access
basic
)
type creds struct {
payload string
security security
}
// AccessCredentials generates grpc credentials based on the access token string
func BasicCredentials(key, secret string) credentials.PerRPCCredentials {
payload := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", key, secret)))
return creds{payload: payload, security: basic}
}
// AccessCredentials generates grpc credentials based on the access token string
func AccessCredentials(token string) credentials.PerRPCCredentials {
return creds{payload: token, security: access}
}
// EmptyCredentials generates grpc credentials that can be used to call unsecured methods such as authentication
func PublicCredentials() credentials.PerRPCCredentials {
return creds{security: public}
}
func (c creds) GetRequestMetadata(ctx context.Context, uri ...string) (md map[string]string, err error) {
switch c.security {
case public:
break //TODO make sure md == nil is ok
case access:
md = map[string]string{AUTH_HEADER: BEARER_PREFIX + c.payload}
case basic:
md = map[string]string{AUTH_HEADER: BASIC_PREFIX + c.payload}
default:
err = fmt.Errorf("Invalid Credentials Security")
}
return
}
func (c creds) RequireTransportSecurity() bool {
return false //TODO change
}
func AuthorizeContext(ctx context.Context, token string) context.Context {
md := metadata.MD{AUTH_HEADER: []string{BEARER_PREFIX + token}}
return metadata.NewContext(ctx, md)
}
func AuthenticateContext(ctx context.Context, key, secret string) context.Context {
payload := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", key, secret)))
md := metadata.MD{AUTH_HEADER: []string{BASIC_PREFIX + payload}}
return metadata.NewContext(ctx, md)
}
func GetBasicCredentials(ctx context.Context) (key, secret string, err error) {
md, ok := metadata.FromContext(ctx)
if !ok {
err = fmt.Errorf("no context metadata")
return
}
payload, ok := md[AUTH_HEADER]
if !ok {
err = fmt.Errorf("missing auth header")
return
}
creds := strings.TrimPrefix(payload[0], BASIC_PREFIX)
if payload[0] == creds {
err = fmt.Errorf("missing basic authorization")
return
}
raw, err := base64.StdEncoding.DecodeString(creds)
kv := strings.Split(string(raw), ":")
if err != nil || len(kv) != 2 {
err = fmt.Errorf("invalid basic authorization payload")
return
}
key = kv[0]
secret = kv[1]
return
}