Skip to content

Commit

Permalink
redefine IoT Core custom authorizer request and response structs (#401)
Browse files Browse the repository at this point in the history
* redefine IoT Core custom authorizer request and response structs as per spec

* make IAM policy structs reusable

* gofmt

* restore deleted structs, add deprecation notices

Co-authored-by: Bryan Moffatt <bmoffatt@users.noreply.github.com>
Co-authored-by: Bryan Moffatt <bmoff2292@gmail.com>
  • Loading branch information
3 people committed May 19, 2022
1 parent 908421f commit ec8f96b
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 56 deletions.
19 changes: 6 additions & 13 deletions events/apigw.go
Expand Up @@ -336,21 +336,14 @@ type APIGatewayV2CustomAuthorizerSimpleResponse struct {
Context map[string]interface{} `json:"context,omitempty"`
}

// APIGatewayCustomAuthorizerPolicy represents an IAM policy.
//
// Note: This type exists for backwards compatibility.
// should reference IAMPolicyDocument directly instead.
type APIGatewayCustomAuthorizerPolicy IAMPolicyDocument

type APIGatewayV2CustomAuthorizerIAMPolicyResponse struct {
PrincipalID string `json:"principalId"`
PolicyDocument APIGatewayCustomAuthorizerPolicy `json:"policyDocument"`
Context map[string]interface{} `json:"context,omitempty"`
}

// APIGatewayCustomAuthorizerPolicy represents an IAM policy
type APIGatewayCustomAuthorizerPolicy struct {
Version string
Statement []IAMPolicyStatement
}

// IAMPolicyStatement represents one statement from IAM policy with action, effect and resource
type IAMPolicyStatement struct {
Action []string
Effect string
Resource []string
}
14 changes: 14 additions & 0 deletions events/iam.go
@@ -0,0 +1,14 @@
package events

// IAMPolicyDocument represents an IAM policy document.
type IAMPolicyDocument struct {
Version string
Statement []IAMPolicyStatement
}

// IAMPolicyStatement represents one statement from IAM policy with action, effect and resource.
type IAMPolicyStatement struct {
Action []string
Effect string
Resource []string
}
48 changes: 30 additions & 18 deletions events/iot.go
@@ -1,34 +1,46 @@
package events

// IoTCustomAuthorizerRequest contains data coming in to a custom IoT device gateway authorizer function.
type IoTCustomAuthorizerRequest struct {
HTTPContext *IoTHTTPContext `json:"httpContext,omitempty"`
MQTTContext *IoTMQTTContext `json:"mqttContext,omitempty"`
TLSContext *IoTTLSContext `json:"tlsContext,omitempty"`
AuthorizationToken string `json:"token"`
TokenSignature string `json:"tokenSignature"`
// IoTCoreCustomAuthorizerRequest represents the request to an IoT Core custom authorizer.
// See https://docs.aws.amazon.com/iot/latest/developerguide/config-custom-auth.html
type IoTCoreCustomAuthorizerRequest struct {
Token string `json:"token"`
SignatureVerified bool `json:"signatureVerified"`
Protocols []string `json:"protocols"`
ProtocolData *IoTCoreProtocolData `json:"protocolData,omitempty"`
ConnectionMetadata *IoTCoreConnectionMetadata `json:"connectionMetadata,omitempty"`
}

type IoTHTTPContext struct {
type IoTCoreProtocolData struct {
TLS *IoTCoreTLSContext `json:"tls,omitempty"`
HTTP *IoTCoreHTTPContext `json:"http,omitempty"`
MQTT *IoTCoreMQTTContext `json:"mqtt,omitempty"`
}

type IoTCoreTLSContext struct {
ServerName string `json:"serverName"`
}

type IoTCoreHTTPContext struct {
Headers map[string]string `json:"headers,omitempty"`
QueryString string `json:"queryString"`
}

type IoTMQTTContext struct {
type IoTCoreMQTTContext struct {
ClientID string `json:"clientId"`
Password []byte `json:"password"`
Username string `json:"username"`
}

type IoTTLSContext struct {
ServerName string `json:"serverName"`
type IoTCoreConnectionMetadata struct {
ID string `json:"id"`
}

// IoTCustomAuthorizerResponse represents the expected format of an IoT device gateway authorization response.
type IoTCustomAuthorizerResponse struct {
IsAuthenticated bool `json:"isAuthenticated"`
PrincipalID string `json:"principalId"`
DisconnectAfterInSeconds int32 `json:"disconnectAfterInSeconds"`
RefreshAfterInSeconds int32 `json:"refreshAfterInSeconds"`
PolicyDocuments []string `json:"policyDocuments"`
// IoTCoreCustomAuthorizerResponse represents the response from an IoT Core custom authorizer.
// See https://docs.aws.amazon.com/iot/latest/developerguide/config-custom-auth.html
type IoTCoreCustomAuthorizerResponse struct {
IsAuthenticated bool `json:"isAuthenticated"`
PrincipalID string `json:"principalId"`
DisconnectAfterInSeconds uint32 `json:"disconnectAfterInSeconds"`
RefreshAfterInSeconds uint32 `json:"refreshAfterInSeconds"`
PolicyDocuments []*IAMPolicyDocument `json:"policyDocuments"`
}
30 changes: 30 additions & 0 deletions events/iot_deprecated.go
@@ -0,0 +1,30 @@
package events

// IoTCustomAuthorizerRequest contains data coming in to a custom IoT device gateway authorizer function.
// Deprecated: Use IoTCoreCustomAuthorizerRequest instead. IoTCustomAuthorizerRequest does not correctly model the request schema
type IoTCustomAuthorizerRequest struct {
HTTPContext *IoTHTTPContext `json:"httpContext,omitempty"`
MQTTContext *IoTMQTTContext `json:"mqttContext,omitempty"`
TLSContext *IoTTLSContext `json:"tlsContext,omitempty"`
AuthorizationToken string `json:"token"`
TokenSignature string `json:"tokenSignature"`
}

// Deprecated: Use IoTCoreHTTPContext
type IoTHTTPContext IoTCoreHTTPContext

// Deprecated: Use IoTCoreMQTTContext
type IoTMQTTContext IoTCoreMQTTContext

// Deprecated: Use IotCoreTLSContext
type IoTTLSContext IoTCoreTLSContext

// IoTCustomAuthorizerResponse represents the expected format of an IoT device gateway authorization response.
// Deprecated: Use IoTCoreCustomAuthorizerResponse. IoTCustomAuthorizerResponse does not correctly model the response schema.
type IoTCustomAuthorizerResponse struct {
IsAuthenticated bool `json:"isAuthenticated"`
PrincipalID string `json:"principalId"`
DisconnectAfterInSeconds int32 `json:"disconnectAfterInSeconds"`
RefreshAfterInSeconds int32 `json:"refreshAfterInSeconds"`
PolicyDocuments []string `json:"policyDocuments"`
}
16 changes: 8 additions & 8 deletions events/iot_test.go
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/aws/aws-lambda-go/events/test"
)

func TestIoTCustomAuthorizerRequestMarshaling(t *testing.T) {
func TestIoTCoreCustomAuthorizerRequestMarshaling(t *testing.T) {

// read json from file
inputJSON, err := ioutil.ReadFile("./testdata/iot-custom-auth-request.json")
Expand All @@ -17,7 +17,7 @@ func TestIoTCustomAuthorizerRequestMarshaling(t *testing.T) {
}

// de-serialize into Go object
var inputEvent IoTCustomAuthorizerRequest
var inputEvent IoTCoreCustomAuthorizerRequest
if err := json.Unmarshal(inputJSON, &inputEvent); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}
Expand All @@ -31,11 +31,11 @@ func TestIoTCustomAuthorizerRequestMarshaling(t *testing.T) {
test.AssertJsonsEqual(t, inputJSON, outputJSON)
}

func TestIoTCustomAuthorizerRequestMalformedJson(t *testing.T) {
test.TestMalformedJson(t, IoTCustomAuthorizerRequest{})
func TestIoTCoreCustomAuthorizerRequestMalformedJson(t *testing.T) {
test.TestMalformedJson(t, IoTCoreCustomAuthorizerRequest{})
}

func TestIoTCustomAuthorizerResponseMarshaling(t *testing.T) {
func TestIoTCoreCustomAuthorizerResponseMarshaling(t *testing.T) {

// read json from file
inputJSON, err := ioutil.ReadFile("./testdata/iot-custom-auth-response.json")
Expand All @@ -44,7 +44,7 @@ func TestIoTCustomAuthorizerResponseMarshaling(t *testing.T) {
}

// de-serialize into Go object
var inputEvent IoTCustomAuthorizerResponse
var inputEvent IoTCoreCustomAuthorizerResponse
if err := json.Unmarshal(inputJSON, &inputEvent); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}
Expand All @@ -58,6 +58,6 @@ func TestIoTCustomAuthorizerResponseMarshaling(t *testing.T) {
test.AssertJsonsEqual(t, inputJSON, outputJSON)
}

func TestIoTCustomAuthorizerResponseMalformedJson(t *testing.T) {
test.TestMalformedJson(t, IoTCustomAuthorizerResponse{})
func TestIoTCoreCustomAuthorizerResponseMalformedJson(t *testing.T) {
test.TestMalformedJson(t, IoTCoreCustomAuthorizerResponse{})
}
36 changes: 21 additions & 15 deletions events/testdata/iot-custom-auth-request.json
@@ -1,18 +1,24 @@
{
"httpContext": {
"headers": {
"Accept-Language" : "en"
"token" :"aToken",
"signatureVerified": true,
"protocols": ["tls", "http", "mqtt"],
"protocolData": {
"tls" : {
"serverName": "serverName"
},
"queryString": "abc"
},
"mqttContext": {
"clientId": "someclient",
"password": "aslkfjwoeiuwekrujwlrueowieurowieurowiuerwleuroiwueroiwueroiuweoriuweoriuwoeiruwoeiur",
"username": "thebestuser"
},
"tlsContext": {
"serverName": "server.stuff.com"
"http": {
"headers": {
"X-Request-ID": "abc123"
},
"queryString": "?foo=bar"
},
"mqtt": {
"username": "myUserName",
"password": "bXlQYXNzd29yZA==",
"clientId": "myClientId"
}
},
"token": "someToken",
"tokenSignature": "somelongtokensignature"
}
"connectionMetadata": {
"id": "e56f08c3-c559-490f-aa9f-7e8427d0f57b"
}
}
13 changes: 11 additions & 2 deletions events/testdata/iot-custom-auth-response.json
Expand Up @@ -4,6 +4,15 @@
"disconnectAfterInSeconds": 86400,
"refreshAfterInSeconds": 300,
"policyDocuments": [
"{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Action\": [\"iot:Subscribe\"], \"Effect\": \"Allow\", \"Resource\": [\"*\"] } ] }"
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["iot:Publish"],
"Effect": "Allow",
"Resource": ["arn:aws:iot:us-east-1:<your_aws_account_id>:topic/customauthtesting"]
}
]
}
]
}
}

0 comments on commit ec8f96b

Please sign in to comment.