finnow/finnow-api/source/auth/data_impl_fs.d

78 lines
2.4 KiB
D

module auth.data_impl_fs;
import handy_httpd.components.optional;
import auth.data;
import auth.model;
/**
* User implementation that stores each user's data in a separate directory.
*/
class FileSystemUserRepository : UserRepository {
import std.path;
import std.file;
import std.json;
private string usersDir;
this(string usersDir = "users") {
this.usersDir = usersDir;
}
Optional!User findByUsername(string username) {
if (
!validateUsername(username) ||
!exists(getUserDir(username)) ||
!exists(getUserDataFile(username))
) {
return Optional!User.empty;
}
return Optional!User.of(readUser(username));
}
User[] findAll() {
User[] users;
foreach (DirEntry entry; dirEntries(this.usersDir, SpanMode.shallow, false)) {
string username = baseName(entry.name);
users ~= readUser(username);
}
return users;
}
User createUser(string username, string passwordHash) {
if (!validateUsername(username)) throw new Exception("Invalid username");
if (exists(getUserDir(username))) throw new Exception("User already exists.");
JSONValue userObj = JSONValue.emptyObject;
userObj.object["passwordHash"] = JSONValue(passwordHash);
string jsonStr = userObj.toPrettyString();
if (!exists(this.usersDir)) mkdir(this.usersDir);
mkdir(getUserDir(username));
std.file.write(getUserDataFile(username), cast(ubyte[]) jsonStr);
return User(username, passwordHash);
}
void deleteByUsername(string username) {
if (validateUsername(username) && exists(getUserDir(username))) {
rmdirRecurse(getUserDir(username));
}
}
private string getUserDir(string username) {
return buildPath(this.usersDir, username);
}
private string getUserDataFile(string username) {
return buildPath(this.usersDir, username, "user-data.json");
}
private User readUser(string username) {
if (!exists(getUserDataFile(username))) {
throw new Exception("User data file for " ~ username ~ " doesn't exist.");
}
JSONValue userObj = parseJSON(readText(getUserDataFile(username)));
return User(
username,
userObj.object["passwordHash"].str
);
}
}