update to latest universal lambda/get access id to createtable

This commit is contained in:
Emil Lerch 2023-10-23 14:11:05 -07:00
parent 79eac7d4f0
commit 8925367a70
Signed by: lobo
GPG Key ID: A7B62D657EF764F8
3 changed files with 53 additions and 12 deletions

View File

@ -12,12 +12,12 @@
.hash = "12208c654deea149cee27eaa45d0e6515c3d8f97d775a4156cbcce0ff424b5d26ea3", .hash = "12208c654deea149cee27eaa45d0e6515c3d8f97d775a4156cbcce0ff424b5d26ea3",
}, },
.universal_lambda_build = .{ .universal_lambda_build = .{
.url = "https://git.lerch.org/lobo/universal-lambda-zig/archive/d8b536651531ee95ceb4fae65ca5f29c5ed6ef29.tar.gz", .url = "https://git.lerch.org/lobo/universal-lambda-zig/archive/6c89380fea51686b775a93d9a68150262a20d513.tar.gz",
.hash = "1220de5b5f23fddb794e2e735ee8312b9cd0d1302d5b8e3902f785e904f515506ccf", .hash = "1220173c05fa58d0dceda2e2de99edb1a68b859006747cfcf80d7c908dda95f87db2",
}, },
.flexilib = .{ .flexilib = .{
.url = "https://git.lerch.org/lobo/flexilib/archive/c44ad2ba84df735421bef23a2ad612968fb50f06.tar.gz", .url = "https://git.lerch.org/lobo/flexilib/archive/3d3dab9c792651477932e2b61c9f4794ac694dcb.tar.gz",
.hash = "122051fdfeefdd75653d3dd678c8aa297150c2893f5fad0728e0d953481383690dbc", .hash = "1220fd7a614fe3c9f6006b630bba528e2ec9dca9c66f5ff10f7e471ad2bdd41b6c89",
}, },
}, },
} }

View File

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const sqlite = @import("sqlite"); const sqlite = @import("sqlite");
pub fn handler(allocator: std.mem.Allocator, event_data: []const u8) ![]const u8 { pub fn handler(allocator: std.mem.Allocator, account_id: []const u8, event_data: []const u8) ![]const u8 {
_ = event_data; _ = event_data;
var db = try sqlite.Db.init(.{ var db = try sqlite.Db.init(.{
.mode = sqlite.Db.Mode{ .File = "donotuse.db" }, .mode = sqlite.Db.Mode{ .File = "donotuse.db" },
@ -11,9 +11,29 @@ pub fn handler(allocator: std.mem.Allocator, event_data: []const u8) ![]const u8
}, },
.threading_mode = .MultiThread, .threading_mode = .MultiThread,
}); });
// DDB minimum table name length is 3. DDB local creates this table with metadata
// This of course is only if the database is first run
// try db.exec(
// \\CREATE TABLE dm (
// \\ TableName TEXT,
// \\ CreationDateTime INTEGER,
// \\ LastDecreaseDate INTEGER,
// \\ LastIncreaseDate INTEGER,
// \\ NumberOfDecreasesToday INTEGER,
// \\ ReadCapacityUnits INTEGER,
// \\ WriteCapacityUnits INTEGER,
// \\ TableInfo BLOB,
// \\ BillingMode INTEGER DEFAULT 0,
// \\ PayPerRequestDateTime INTEGER DEFAULT 0,
// \\ PRIMARY KEY(TableName)
// );
try db.exec("CREATE TABLE user(id integer primary key, age integer, name text)", .{}, .{}); try db.exec("CREATE TABLE user(id integer primary key, age integer, name text)", .{}, .{});
var al = std.ArrayList(u8).init(allocator); var al = std.ArrayList(u8).init(allocator);
var writer = al.writer(); var writer = al.writer();
try writer.print("table created\n", .{}); try writer.print("table created for account {s}\n", .{account_id});
return al.items; return al.items;
// This is what the music collection sample creates
// CREATE TABLE IF NOT EXISTS "MusicCollection" (hashKey TEXT DEFAULT NULL, rangeKey TEXT DEFAULT NULL, hashValue BLOB NOT NULL, rangeValue BLOB NOT NULL, itemSize INTEGER DEFAULT 0, ObjectJSON BLOB NOT NULL, PRIMARY KEY(hashKey, rangeKey));
// CREATE INDEX "MusicCollection*HVI" ON "MusicCollection" (hashValue);
} }

View File

@ -7,8 +7,8 @@ pub const std_options = struct {
pub const log_scope_levels = &[_]std.log.ScopeLevel{.{ .scope = .aws_signing, .level = .info }}; pub const log_scope_levels = &[_]std.log.ScopeLevel{.{ .scope = .aws_signing, .level = .info }};
}; };
pub fn main() !void { pub fn main() !u8 {
try universal_lambda.run(null, handler); return try universal_lambda.run(null, handler);
} }
var test_credential: signing.Credentials = undefined; var test_credential: signing.Credentials = undefined;
@ -39,17 +39,38 @@ pub fn handler(allocator: std.mem.Allocator, event_data: []const u8, context: un
// X-Amz-Target: DynamoDB_20120810.CreateTable // X-Amz-Target: DynamoDB_20120810.CreateTable
const target_value = headers.http_headers.getFirstValue("X-Amz-Target").?; const target_value = headers.http_headers.getFirstValue("X-Amz-Target").?;
const operation = target_value[std.mem.lastIndexOf(u8, target_value, ".").? + 1 ..]; const operation = target_value[std.mem.lastIndexOf(u8, target_value, ".").? + 1 ..];
const account_id = try accountId(allocator, headers.http_headers.*);
if (std.ascii.eqlIgnoreCase("CreateTable", operation)) if (std.ascii.eqlIgnoreCase("CreateTable", operation))
return @import("createtable.zig").handler(allocator, event_data); return @import("createtable.zig").handler(allocator, account_id, event_data);
try std.io.getStdErr().writer().print("Operation '{s}' unsupported\n", .{operation}); try std.io.getStdErr().writer().print("Operation '{s}' unsupported\n", .{operation});
return error.OperationUnsupported; return error.OperationUnsupported;
} }
// TODO: Get hook these functions up to IAM for great good
fn getCreds(access: []const u8) ?signing.Credentials { fn getCreds(access: []const u8) ?signing.Credentials {
if (std.mem.eql(u8, access, "ACCESS")) return test_credential; if (std.mem.eql(u8, access, "ACCESS")) return test_credential;
return null; return null;
} }
fn accountForAccessKey(allocator: std.mem.Allocator, access_key: []const u8) ![]const u8 {
_ = allocator;
_ = access_key;
return "1234, Get your woman, on the floor";
}
/// Function assumes an authenticated request, so signing.verify must be called
/// and returned true before calling this function. If authentication header
/// is not found, environment variable will be used
fn accountId(allocator: std.mem.Allocator, headers: std.http.Headers) ![]const u8 {
const auth_header = headers.getFirstValue("Authorization");
if (auth_header) |h| {
// AWS4-HMAC-SHA256 Credential=ACCESS/20230908/us-west-2/s3/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class, Signature=fcc43ce73a34c9bd1ddf17e8a435f46a859812822f944f9eeb2aabcd64b03523
const start = std.mem.indexOf(u8, h, "Credential=").? + "Credential=".len;
var split = std.mem.split(u8, h[start..], "/");
return try accountForAccessKey(allocator, split.first());
}
return try iamAccountId(allocator);
}
// These never need to be freed because we will need them throughout the program // These never need to be freed because we will need them throughout the program
var iam_account_id: ?[]const u8 = null; var iam_account_id: ?[]const u8 = null;
var iam_access_key: ?[]const u8 = null; var iam_access_key: ?[]const u8 = null;
@ -70,9 +91,9 @@ fn iamSecretKey(allocator: std.mem.Allocator) ![]const u8 {
return try getVariable(allocator, &iam_secret_key, "IAM_SECRET_KEY"); return try getVariable(allocator, &iam_secret_key, "IAM_SECRET_KEY");
} }
fn getVariable(allocator: std.mem.Allocator, global: *?[]const u8, env_var_name: []const u8) ![]const u8 { fn getVariable(allocator: std.mem.Allocator, global: *?[]const u8, env_var_name: []const u8) ![]const u8 {
if (global) |gl| return gl; if (global.*) |gl| return gl;
global = try std.process.getEnvVarOwned(allocator, env_var_name); global.* = try std.process.getEnvVarOwned(allocator, env_var_name);
return global.?; return global.*.?;
} }
test "simple test" { test "simple test" {