This repository has been archived by the owner on Jan 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
auth.go
101 lines (83 loc) · 2.26 KB
/
auth.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
package main
import (
"encoding/json"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/payfazz/go-errors/v2"
"gopkg.in/square/go-jose.v2"
"github.com/payfazz/fazz-ecr/aws-lambda/fazz-ecr/util/iam"
awsconfig "github.com/payfazz/fazz-ecr/config/aws"
oidcconfig "github.com/payfazz/fazz-ecr/config/oidc"
)
func getAuth(token string) (string, []string, error) {
jws, err := jose.ParseSigned(token)
if err != nil {
return "", nil, nil
}
if len(jws.Signatures) == 0 {
return "", nil, nil
}
switch jws.Signatures[0].Header.ExtraHeaders["typ"] {
case "statickey":
return authFromStaticKey(jws)
default:
return authFromJwt(jws)
}
}
func authFromStaticKey(jwt *jose.JSONWebSignature) (string, []string, error) {
envSession, err := iam.EnvSession()
if err != nil {
return "", nil, errors.Trace(err)
}
ddbsvc := dynamodb.New(envSession)
result, err := ddbsvc.GetItem(&dynamodb.GetItemInput{
TableName: aws.String(awsconfig.StaticKeyTableName()),
Key: map[string]*dynamodb.AttributeValue{
"id": {S: aws.String(string(jwt.UnsafePayloadWithoutVerification()))},
},
})
if err != nil {
return "", nil, errors.Trace(err)
}
if len(result.Item) == 0 {
return "", nil, nil
}
return aws.StringValue(result.Item["email"].S), aws.StringValueSlice(result.Item["groups"].SS), nil
}
func authFromJwt(jwt *jose.JSONWebSignature) (string, []string, error) {
sig := jwt.Signatures[0]
if sig.Header.Algorithm == "none" || sig.Header.Algorithm == "" {
return "", nil, nil
}
key, err := getJwtKeyByID(sig.Header.KeyID)
if err != nil {
return "", nil, err
}
if key == nil {
return "", nil, nil
}
data, err := jwt.Verify(key)
if err != nil {
return "", nil, nil
}
var jwtBody struct {
Iss string `json:"iss"`
Aud string `json:"aud"`
Exp int64 `json:"exp"`
Iat int64 `json:"iat"`
Email string `json:"email"`
Groups []string `json:"groups"`
}
if err := json.Unmarshal(data, &jwtBody); err != nil {
return "", nil, nil
}
if jwtBody.Iss != oidcconfig.Issuer || jwtBody.Aud != oidcconfig.ClientID {
return "", nil, nil
}
now := time.Now().Unix()
if !(jwtBody.Iat <= now && now <= jwtBody.Exp) {
return "", nil, nil
}
return jwtBody.Email, jwtBody.Groups, nil
}