Skip to content

Commit fa050df

Browse files
committed
Add S3 Object Lambda event object
1 parent 087590c commit fa050df

File tree

5 files changed

+306
-1
lines changed

5 files changed

+306
-1
lines changed

Libraries/src/Amazon.Lambda.S3Events/Amazon.Lambda.S3Events.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<PropertyGroup>
66
<Description>Amazon Lambda .NET Core support - S3Events package.</Description>
7-
<TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks>
7+
<TargetFrameworks>netstandard1.3;netstandard2.0;netcoreapp3.1</TargetFrameworks>
88
<AssemblyTitle>Amazon.Lambda.S3Events</AssemblyTitle>
99
<VersionPrefix>1.2.0</VersionPrefix>
1010
<AssemblyName>Amazon.Lambda.S3Events</AssemblyName>
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Amazon.Lambda.S3Events
6+
{
7+
/// <summary>
8+
/// Class representing the S3 Object Lambda event.
9+
///
10+
/// S3 Developer Guide explaining the event data.
11+
/// https://docs.aws.amazon.com/AmazonS3/latest/userguide/olap-writing-lambda.html
12+
/// </summary>
13+
public class S3ObjectLambdaEvent
14+
{
15+
/// <summary>
16+
/// The Amazon S3 request ID for this request. We recommend that you log this value to help with debugging.
17+
/// </summary>
18+
#if NETCOREAPP3_1
19+
[System.Text.Json.Serialization.JsonPropertyName("xAmzRequestId")]
20+
#endif
21+
public string XAmzRequestId { get; set; }
22+
23+
/// <summary>
24+
/// The input and output details for connections to Amazon S3 and S3 Object Lambda.
25+
/// </summary>
26+
public GetObjectContextType GetObjectContext { get; set; }
27+
28+
/// <summary>
29+
/// Configuration information about the S3 Object Lambda access point.
30+
/// </summary>
31+
public ConfigurationType Configuration { get; set; }
32+
33+
/// <summary>
34+
/// Information about the original call to S3 Object Lambda.
35+
/// </summary>
36+
public UserRequestType UserRequest { get; set; }
37+
38+
/// <summary>
39+
/// Details about the identity that made the call to S3 Object Lambda.
40+
/// </summary>
41+
public UserIdentityType UserIdentity { get; set; }
42+
43+
/// <summary>
44+
/// The version ID of the context provided. The format of this field is {Major Version}.{Minor Version}.
45+
/// </summary>
46+
public string ProtocolVersion { get; set; }
47+
48+
/// <summary>
49+
/// The input and output details for connections to Amazon S3 and S3 Object Lambda.
50+
/// </summary>
51+
public class GetObjectContextType
52+
{
53+
/// <summary>
54+
/// A presigned URL that can be used to fetch the original object from Amazon S3. The URL is signed
55+
/// using the original caller’s identity, and their permissions will apply when the URL is used.
56+
/// If there are signed headers in the URL, the Lambda function must include these in the call to
57+
/// Amazon S3, except for the Host.
58+
/// </summary>
59+
public string InputS3Url { get; set; }
60+
61+
/// <summary>
62+
/// A presigned URL that can be used to fetch the original object from Amazon S3. The URL is signed
63+
/// using the original caller’s identity, and their permissions will apply when the URL is used. If
64+
/// there are signed headers in the URL, the Lambda function must include these in the call to
65+
/// Amazon S3, except for the Host.
66+
/// </summary>
67+
public string OutputRoute { get; set; }
68+
69+
/// <summary>
70+
/// An opaque token used by S3 Object Lambda to match the WriteGetObjectResponse call with the
71+
/// original caller.
72+
/// </summary>
73+
public string OutputToken { get; set; }
74+
}
75+
76+
/// <summary>
77+
/// Configuration information about the S3 Object Lambda access point.
78+
/// </summary>
79+
public class ConfigurationType
80+
{
81+
/// <summary>
82+
/// The Amazon Resource Name (ARN) of the S3 Object Lambda access point that received this request.
83+
/// </summary>
84+
public string AccessPointArn { get; set; }
85+
86+
/// <summary>
87+
/// The ARN of the supporting access point that is specified in the S3 Object Lambda access point configuration.
88+
/// </summary>
89+
public string SupportingAccessPointArn { get; set; }
90+
91+
/// <summary>
92+
/// ustom data that is applied to the S3 Object Lambda access point configuration. S3 Object Lambda treats
93+
/// this as an opaque string, so it might need to be decoded before use.
94+
/// </summary>
95+
public string Payload { get; set; }
96+
97+
}
98+
99+
/// <summary>
100+
/// Information about the original call to S3 Object Lambda.
101+
/// </summary>
102+
public class UserRequestType
103+
{
104+
/// <summary>
105+
/// The decoded URL of the request as received by S3 Object Lambda,
106+
/// excluding any authorization-related query parameters.
107+
/// </summary>
108+
public string Url { get; set; }
109+
110+
/// <summary>
111+
/// A map of string to strings containing the HTTP headers and their values from the original call, excluding
112+
/// any authorization-related headers. If the same header appears multiple times, their values are
113+
/// combined into a comma-delimited list.
114+
/// </summary>
115+
public IDictionary<string, string> Headers { get; set; }
116+
}
117+
118+
/// <summary>
119+
/// Details about the identity that made the call to S3 Object Lambda.
120+
/// </summary>
121+
public class UserIdentityType
122+
{
123+
/// <summary>
124+
/// The type of identity.
125+
/// </summary>
126+
public string Type { get; set; }
127+
128+
/// <summary>
129+
/// The unique identifier for the identity that made the call.
130+
/// </summary>
131+
public string PrincipalId { get; set; }
132+
133+
/// <summary>
134+
/// The ARN of the principal that made the call. The last section of the ARN contains the user or role that made the call.
135+
/// </summary>
136+
public string Arn { get; set; }
137+
138+
/// <summary>
139+
/// The AWS account to which the identity belongs.
140+
/// </summary>
141+
public string AccountId { get; set; }
142+
143+
/// <summary>
144+
/// The AWS Access Key Id for the identity.
145+
/// </summary>
146+
public string AccessKeyId { get; set; }
147+
148+
/// <summary>
149+
/// If the request was made with temporary security credentials, this element provides information about the
150+
/// session that was created for those credentials.
151+
/// </summary>
152+
public SessionContextType SessionContext { get; set; }
153+
}
154+
155+
/// <summary>
156+
/// The information about temporary session credentials used by the identity.
157+
/// </summary>
158+
public class SessionContextType
159+
{
160+
/// <summary>
161+
/// Attributes for the temporary session credentials
162+
/// </summary>
163+
public SessionContextAttributesType Attributes { get; set; }
164+
165+
/// <summary>
166+
/// If the request was made with temporary security credentials, this element provides information about how the credentials were obtained.
167+
/// </summary>
168+
public SessionIssuerType SessionIssuer { get; set; }
169+
}
170+
171+
/// <summary>
172+
/// Attributes of the temporary session credentials
173+
/// </summary>
174+
public class SessionContextAttributesType
175+
{
176+
/// <summary>
177+
/// Identifies whether MFA authentication was used when obtaining temporary credentials.
178+
/// </summary>
179+
public string MfaAuthenticated { get; set; }
180+
181+
/// <summary>
182+
/// The create date of the temporary session credentials.
183+
/// </summary>
184+
public string CreationDate { get; set; }
185+
}
186+
187+
/// <summary>
188+
/// Information about the issuer of the temporary session credentials.
189+
/// </summary>
190+
public class SessionIssuerType
191+
{
192+
/// <summary>
193+
/// The type of issuer of the temporary session credentials.
194+
/// </summary>
195+
public string Type { get; set; }
196+
197+
/// <summary>
198+
/// The principal id of the issuer of the temporary session credentials.
199+
/// </summary>
200+
public string PrincipalId { get; set; }
201+
202+
/// <summary>
203+
/// The arn of the issuer of the temporary session credentials.
204+
/// </summary>
205+
public string Arn { get; set; }
206+
207+
/// <summary>
208+
/// The account id of the issuer of the temporary session credentials.
209+
/// </summary>
210+
public string AccountId { get; set; }
211+
212+
/// <summary>
213+
/// The user name of the issuer of the temporary session credentials.
214+
/// </summary>
215+
public string UserName { get; set; }
216+
}
217+
}
218+
}

Libraries/test/EventsTests.Shared/EventTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,50 @@ public void SetHeadersToHttpApiV2Response()
184184
Assert.Equal("value3", response.Headers["name1"]);
185185
}
186186

187+
[Theory]
188+
[InlineData(typeof(JsonSerializer))]
189+
#if NETCOREAPP_3_1
190+
[InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
191+
[InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
192+
#endif
193+
public void S3ObjectLambdaEventTest(Type serializerType)
194+
{
195+
var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
196+
using (var fileStream = LoadJsonTestFile("s3-object-lambda-event.json"))
197+
{
198+
var s3Event = serializer.Deserialize<S3ObjectLambdaEvent>(fileStream);
199+
200+
Assert.Equal("requestId", s3Event.XAmzRequestId);
201+
Assert.Equal("https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=<snip>", s3Event.GetObjectContext.InputS3Url);
202+
Assert.Equal("io-use1-001", s3Event.GetObjectContext.OutputRoute);
203+
Assert.Equal("OutputToken", s3Event.GetObjectContext.OutputToken);
204+
205+
Assert.Equal("arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap", s3Event.Configuration.AccessPointArn);
206+
Assert.Equal("arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap", s3Event.Configuration.SupportingAccessPointArn);
207+
Assert.Equal("{}", s3Event.Configuration.Payload);
208+
209+
Assert.Equal("https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example", s3Event.UserRequest.Url);
210+
Assert.Equal("object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com", s3Event.UserRequest.Headers["Host"]);
211+
212+
Assert.Equal("AssumedRole", s3Event.UserIdentity.Type);
213+
Assert.Equal("principalId", s3Event.UserIdentity.PrincipalId);
214+
Assert.Equal("arn:aws:sts::111122223333:assumed-role/Admin/example", s3Event.UserIdentity.Arn);
215+
Assert.Equal("111122223333", s3Event.UserIdentity.AccountId);
216+
Assert.Equal("accessKeyId", s3Event.UserIdentity.AccessKeyId);
217+
218+
Assert.Equal("false", s3Event.UserIdentity.SessionContext.Attributes.MfaAuthenticated);
219+
Assert.Equal("Wed Mar 10 23:41:52 UTC 2021", s3Event.UserIdentity.SessionContext.Attributes.CreationDate);
220+
221+
Assert.Equal("Role", s3Event.UserIdentity.SessionContext.SessionIssuer.Type);
222+
Assert.Equal("principalId", s3Event.UserIdentity.SessionContext.SessionIssuer.PrincipalId);
223+
Assert.Equal("arn:aws:iam::111122223333:role/Admin", s3Event.UserIdentity.SessionContext.SessionIssuer.Arn);
224+
Assert.Equal("111122223333", s3Event.UserIdentity.SessionContext.SessionIssuer.AccountId);
225+
Assert.Equal("Admin", s3Event.UserIdentity.SessionContext.SessionIssuer.UserName);
226+
227+
Assert.Equal("1.00", s3Event.ProtocolVersion);
228+
}
229+
}
230+
187231
[Theory]
188232
[InlineData(typeof(JsonSerializer))]
189233
#if NETCOREAPP_3_1

Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<Content Include="$(MSBuildThisFileDirectory)logs-event.json" />
3131
<Content Include="$(MSBuildThisFileDirectory)proxy-event.json" />
3232
<Content Include="$(MSBuildThisFileDirectory)s3-event.json" />
33+
<Content Include="$(MSBuildThisFileDirectory)s3-object-lambda-event.json" />
3334
<Content Include="$(MSBuildThisFileDirectory)scheduled-event.json" />
3435
<Content Include="$(MSBuildThisFileDirectory)simple-email-event-lambda.json" />
3536
<Content Include="$(MSBuildThisFileDirectory)simple-email-event-s3.json" />
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"xAmzRequestId": "requestId",
3+
"getObjectContext": {
4+
"inputS3Url": "https://my-s3-ap-111122223333.s3-accesspoint.us-east-1.amazonaws.com/example?X-Amz-Security-Token=<snip>",
5+
"outputRoute": "io-use1-001",
6+
"outputToken": "OutputToken"
7+
},
8+
"configuration": {
9+
"accessPointArn": "arn:aws:s3-object-lambda:us-east-1:111122223333:accesspoint/example-object-lambda-ap",
10+
"supportingAccessPointArn": "arn:aws:s3:us-east-1:111122223333:accesspoint/example-ap",
11+
"payload": "{}"
12+
},
13+
"userRequest": {
14+
"url": "https://object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com/example",
15+
"headers": {
16+
"Host": "object-lambda-111122223333.s3-object-lambda.us-east-1.amazonaws.com",
17+
"Accept-Encoding": "identity",
18+
"X-Amz-Content-SHA256": "e3b0c44298fc1example"
19+
}
20+
},
21+
"userIdentity": {
22+
"type": "AssumedRole",
23+
"principalId": "principalId",
24+
"arn": "arn:aws:sts::111122223333:assumed-role/Admin/example",
25+
"accountId": "111122223333",
26+
"accessKeyId": "accessKeyId",
27+
"sessionContext": {
28+
"attributes": {
29+
"mfaAuthenticated": "false",
30+
"creationDate": "Wed Mar 10 23:41:52 UTC 2021"
31+
},
32+
"sessionIssuer": {
33+
"type": "Role",
34+
"principalId": "principalId",
35+
"arn": "arn:aws:iam::111122223333:role/Admin",
36+
"accountId": "111122223333",
37+
"userName": "Admin"
38+
}
39+
}
40+
},
41+
"protocolVersion": "1.00"
42+
}

0 commit comments

Comments
 (0)