Take community url as string

This commit is contained in:
jaina heartles 2022-08-01 22:18:54 -07:00
parent 6c15849882
commit bdd2d48a87

View file

@ -41,6 +41,14 @@ pub fn free(alloc: std.mem.Allocator, val: anytype) void {
} }
} }
pub fn firstIndexOf(str: []const u8, ch: u8) ?usize {
for (str) |c, i| {
if (c == ch) return i;
}
return null;
}
pub fn CreateInfo(comptime T: type) type { pub fn CreateInfo(comptime T: type) type {
const t_fields = std.meta.fields(T); const t_fields = std.meta.fields(T);
var fields: [t_fields.len - 1]std.builtin.Type.StructField = undefined; var fields: [t_fields.len - 1]std.builtin.Type.StructField = undefined;
@ -79,7 +87,6 @@ pub const Scheme = models.Community.Scheme;
pub const CommunityCreateOptions = struct { pub const CommunityCreateOptions = struct {
name: []const u8, name: []const u8,
host: []const u8, host: []const u8,
scheme: Scheme,
}; };
pub const RegistrationInfo = struct { pub const RegistrationInfo = struct {
@ -238,19 +245,42 @@ fn ApiConn(comptime DbConn: type) type {
} }
pub fn createCommunity(self: *Self, info: CommunityCreateOptions) !models.Community { pub fn createCommunity(self: *Self, info: CommunityCreateOptions) !models.Community {
// TODO: Take url as single string and parse it const scheme_len = firstIndexOf(info.host, ':') orelse return error.InvalidHost;
const scheme_str = info.host[0..scheme_len];
const scheme = std.meta.stringToEnum(models.Community.Scheme, scheme_str) orelse return error.UnsupportedScheme;
const host = blk: {
// host must be in the format "{scheme}://{host}"
if (info.host.len <= scheme_len + ("://").len or
info.host[scheme_len] != ':' or
info.host[scheme_len + 1] != '/' or
info.host[scheme_len + 2] != '/') return error.InvalidHost;
const host = info.host[scheme_len + 3 ..];
// community cannot use non-default ports (except for testing)
// NOTE: Do not add, say localhost and localhost:80 or bugs may happen.
// Avoid using non-default ports unless a test can't be conducted without it.
if (firstIndexOf(host, ':') != null and builtin.mode != .Debug) return error.InvalidHost;
// community cannot be hosted on a path
if (firstIndexOf(host, '/') != null) return error.InvalidHost;
break :blk host;
};
const id = Uuid.randV4(prng.random()); const id = Uuid.randV4(prng.random());
const now = DateTime.now(); const now = DateTime.now();
// Require TLS on production builds // Require TLS on production builds
if (info.scheme != .https and builtin.mode != .Debug) return error.UnsupportedScheme; if (scheme != .https and builtin.mode != .Debug) return error.UnsupportedScheme;
const community = models.Community{ const community = models.Community{
.id = id, .id = id,
.created_at = now, .created_at = now,
.name = info.name, .name = info.name,
.host = info.host, .host = host,
.scheme = info.scheme, .scheme = scheme,
}; };
try self.db.insert(models.Community, community); try self.db.insert(models.Community, community);