103 lines
3.8 KiB
D
103 lines
3.8 KiB
D
module profile.api;
|
|
|
|
import std.json;
|
|
import asdf;
|
|
import handy_http_primitives;
|
|
import handy_http_data.json;
|
|
import handy_http_handlers.path_handler : getPathParamAs;
|
|
import slf4d;
|
|
|
|
import profile.model;
|
|
import profile.service;
|
|
import profile.data;
|
|
import profile.data_impl_sqlite;
|
|
import auth.model;
|
|
import auth.service;
|
|
|
|
struct NewProfilePayload {
|
|
string name;
|
|
}
|
|
|
|
void handleCreateNewProfile(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
auto payload = readJsonBodyAs!NewProfilePayload(request);
|
|
string name = payload.name;
|
|
if (!validateProfileName(name)) {
|
|
response.status = HttpStatus.BAD_REQUEST;
|
|
response.writeBodyString("Invalid profile name.");
|
|
return;
|
|
}
|
|
AuthContext auth = getAuthContext(request);
|
|
ProfileRepository profileRepo = new FileSystemProfileRepository(auth.user.username);
|
|
Profile p = profileRepo.createProfile(name);
|
|
writeJsonBody(response, p);
|
|
}
|
|
|
|
void handleGetProfiles(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
AuthContext auth = getAuthContext(request);
|
|
ProfileRepository profileRepo = new FileSystemProfileRepository(auth.user.username);
|
|
Profile[] profiles = profileRepo.findAll();
|
|
writeJsonBody(response, profiles);
|
|
}
|
|
|
|
void handleGetProfile(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
ProfileContext profileCtx = getProfileContextOrThrow(request);
|
|
writeJsonBody(response, profileCtx.profile);
|
|
}
|
|
|
|
void handleDeleteProfile(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
string name = request.getPathParamAs!string("profile");
|
|
if (!validateProfileName(name)) {
|
|
response.status = HttpStatus.BAD_REQUEST;
|
|
response.writeBodyString("Invalid profile name.");
|
|
return;
|
|
}
|
|
AuthContext auth = getAuthContext(request);
|
|
ProfileRepository profileRepo = new FileSystemProfileRepository(auth.user.username);
|
|
profileRepo.deleteByName(name);
|
|
}
|
|
|
|
void handleGetProperties(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
ProfileContext profileCtx = getProfileContextOrThrow(request);
|
|
ProfileRepository profileRepo = new FileSystemProfileRepository(profileCtx.user.username);
|
|
ProfileDataSource ds = profileRepo.getDataSource(profileCtx.profile);
|
|
auto propsRepo = ds.getPropertiesRepository();
|
|
ProfileProperty[] props = propsRepo.findAll();
|
|
writeJsonBody(response, props);
|
|
}
|
|
|
|
void handleDownloadProfile(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
|
ProfileContext profileCtx = getProfileContextOrThrow(request);
|
|
ProfileRepository profileRepo = new FileSystemProfileRepository(profileCtx.user.username);
|
|
Optional!ProfileDownloadData data = profileRepo.getProfileData(profileCtx.profile.name);
|
|
if (data.isNull) {
|
|
response.status = HttpStatus.NOT_FOUND;
|
|
response.writeBodyString("Profile data not found.");
|
|
return;
|
|
}
|
|
|
|
import streams : StreamResult;
|
|
import std.conv : to;
|
|
response.headers.add("Content-Type", data.value.contentType);
|
|
response.headers.add("Content-Disposition", "attachment; filename=" ~ data.value.filename);
|
|
response.headers.add("Content-Length", data.value.size.to!string);
|
|
// Transfer the file:
|
|
StreamResult result;
|
|
ubyte[4096] buffer;
|
|
ulong bytesWritten = 0;
|
|
while (bytesWritten < data.value.size) {
|
|
result = data.value.inputStream.readFromStream(buffer);
|
|
if (result.hasError) {
|
|
errorF!"Failed to read from stream: %s"(result.error);
|
|
return;
|
|
}
|
|
if (result.count == 0) {
|
|
return; // Done!
|
|
}
|
|
result = response.outputStream.writeToStream(buffer[0 .. result.count]);
|
|
if (result.hasError) {
|
|
errorF!"Failed to write to stream: %s"(result.error);
|
|
return;
|
|
}
|
|
bytesWritten += result.count;
|
|
}
|
|
} |