mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-29 07:21:27 +00:00
Merge pull request 'Move to JSON controlled server settings' (#3) from inex/selfprivacy-rest-api:json-manipulations into master
Reviewed-on: https://git.selfprivacy.org/ilchub/selfprivacy-rest-api/pulls/3
This commit is contained in:
commit
a86f2fe2bb
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"python.formatting.provider": "black"
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
requires = ["setuptools", "wheel", "portalocker"]
|
||||
build-backend = "setuptools.build_meta"
|
|
@ -3,3 +3,4 @@ flask
|
|||
flask_restful
|
||||
flask_socketio
|
||||
setuptools
|
||||
portalocker
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask_restful import Resource
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable Bitwarden
|
||||
class EnableBitwarden(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/passmgr/bitwarden.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/passmgr/bitwarden.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "bitwarden" not in data:
|
||||
data["bitwarden"] = {}
|
||||
data["bitwarden"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Bitwarden enabled",
|
||||
}
|
||||
|
||||
|
@ -24,17 +30,21 @@ class EnableBitwarden(Resource):
|
|||
# Disable Bitwarden
|
||||
class DisableBitwarden(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/passmgr/bitwarden.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = true;", "enable = false;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/passmgr/bitwarden.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "bitwarden" not in data:
|
||||
data["bitwarden"] = {}
|
||||
data["bitwarden"]["enable"] = False
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Bitwarden disabled",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask_restful import Resource
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable Gitea
|
||||
class EnableGitea(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/git/gitea.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/git/gitea.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "gitea" not in data:
|
||||
data["gitea"] = {}
|
||||
data["gitea"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Gitea enabled",
|
||||
}
|
||||
|
||||
|
@ -24,17 +30,21 @@ class EnableGitea(Resource):
|
|||
# Disable Gitea
|
||||
class DisableGitea(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/git/gitea.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = true;", "enable = false;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/git/gitea.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "gitea" not in data:
|
||||
data["gitea"] = {}
|
||||
data["gitea"]["enable"] = False
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Gitea disabled",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask_restful import Resource
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable Nextcloud
|
||||
class EnableNextcloud(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/nextcloud/nextcloud.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/nextcloud/nextcloud.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "nextcloud" not in data:
|
||||
data["nextcloud"] = {}
|
||||
data["nextcloud"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Nextcloud enabled",
|
||||
}
|
||||
|
||||
|
@ -24,17 +30,21 @@ class EnableNextcloud(Resource):
|
|||
# Disable Nextcloud
|
||||
class DisableNextcloud(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/nextcloud/nextcloud.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = true;", "enable = false;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/nextcloud/nextcloud.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "nextcloud" not in data:
|
||||
data["nextcloud"] = {}
|
||||
data["nextcloud"]["enable"] = False
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Nextcloud disabled",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask_restful import Resource
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable OpenConnect VPN server
|
||||
class EnableOcserv(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/vpn/ocserv.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/vpn/ocserv.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "ocserv" not in data:
|
||||
data["ocserv"] = {}
|
||||
data["ocserv"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "OpenConnect VPN server enabled",
|
||||
}
|
||||
|
||||
|
@ -24,17 +30,21 @@ class EnableOcserv(Resource):
|
|||
# Disable OpenConnect VPN server
|
||||
class DisableOcserv(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/vpn/ocserv.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = true;", "enable = false;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/vpn/ocserv.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "ocserv" not in data:
|
||||
data["ocserv"] = {}
|
||||
data["ocserv"]["enable"] = False
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "OpenConnect VPN server disabled",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask_restful import Resource
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable Pleroma
|
||||
class EnablePleroma(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/social/pleroma.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/social/pleroma.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "pleroma" not in data:
|
||||
data["pleroma"] = {}
|
||||
data["pleroma"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Pleroma enabled",
|
||||
}
|
||||
|
||||
|
@ -24,17 +30,21 @@ class EnablePleroma(Resource):
|
|||
# Disable Pleroma
|
||||
class DisablePleroma(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/social/pleroma.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = true;", "enable = false;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/social/pleroma.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "pleroma" not in data:
|
||||
data["pleroma"] = {}
|
||||
data["pleroma"]["enable"] = False
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "Pleroma disabled",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
#!/usr/bin/env python3
|
||||
from flask import Blueprint, request
|
||||
from flask_restful import Resource, reqparse
|
||||
import portalocker
|
||||
import json
|
||||
|
||||
from selfprivacy_api.resources.services import api
|
||||
|
||||
# Enable SSH
|
||||
class EnableSSH(Resource):
|
||||
def post(self):
|
||||
readOnlyFileDescriptor = open("/etc/nixos/configuration.nix", "rt")
|
||||
fileContent = readOnlyFileDescriptor.read()
|
||||
fileContent = fileContent.replace("enable = false;", "enable = true;")
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor = open("/etc/nixos/configuration.nix", "wt")
|
||||
writeOperationDescriptor = readWriteFileDescriptor.write(fileContent)
|
||||
readWriteFileDescriptor.close()
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "ssh" not in data:
|
||||
data["ssh"] = {}
|
||||
data["ssh"]["enable"] = True
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": writeOperationDescriptor,
|
||||
"message": "SSH enabled",
|
||||
}
|
||||
|
||||
|
@ -33,41 +39,28 @@ class WriteSSHKey(Resource):
|
|||
|
||||
publicKey = args["public_key"]
|
||||
|
||||
print("[INFO] Opening /etc/nixos/configuration.nix...", sep="")
|
||||
readOnlyFileDescriptor = open("/etc/nixos/configuration.nix", "r")
|
||||
print("done")
|
||||
fileContent = list()
|
||||
index = int(0)
|
||||
|
||||
print("[INFO] Reading file content...", sep="")
|
||||
|
||||
while True:
|
||||
line = readOnlyFileDescriptor.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
else:
|
||||
fileContent.append(line)
|
||||
print("[DEBUG] Read line!")
|
||||
|
||||
for line in fileContent:
|
||||
index += 1
|
||||
if "openssh.authorizedKeys.keys = [" in line:
|
||||
print("[DEBUG] Found SSH key configuration snippet match!")
|
||||
print("[INFO] Writing new SSH key", sep="")
|
||||
fileContent.append('\n "' + publicKey + '"')
|
||||
print("done")
|
||||
break
|
||||
|
||||
print("[INFO] Writing data from memory to file...", sep="")
|
||||
readWriteFileDescriptor = open("/etc/nixos/configuration.nix", "w")
|
||||
print("done")
|
||||
operationResult = readWriteFileDescriptor.writelines(fileContent)
|
||||
with portalocker.Lock("/etc/nixos/userdata/userdata.json", "r+") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
if "ssh" not in data:
|
||||
data["ssh"] = {}
|
||||
# Return 400 if key already in array
|
||||
for key in data["ssh"]["rootSshKeys"]:
|
||||
if key == publicKey:
|
||||
return {
|
||||
"error": "Key already exists",
|
||||
}, 400
|
||||
data["ssh"]["rootSshKeys"].append(publicKey)
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {
|
||||
"status": 0,
|
||||
"descriptor": operationResult,
|
||||
"message": "New SSH key successfully written to /etc/nixos/configuration.nix",
|
||||
"message": "New SSH key successfully written",
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
from flask import Blueprint, jsonify, request
|
||||
from flask_restful import Resource, Api
|
||||
import subprocess
|
||||
import portalocker
|
||||
import json
|
||||
import re
|
||||
|
||||
from selfprivacy_api import resources
|
||||
|
||||
|
@ -24,123 +27,62 @@ class Users(Resource):
|
|||
hashedPassword = hashedPassword.decode("ascii")
|
||||
hashedPassword = hashedPassword.rstrip()
|
||||
|
||||
print("[TRACE] {0}".format(hashedPassword))
|
||||
|
||||
print("[INFO] Opening /etc/nixos/users.nix...", sep="")
|
||||
readOnlyFileDescriptor = open("/etc/nixos/users.nix", "r")
|
||||
print("done")
|
||||
fileContent = list()
|
||||
index = int(0)
|
||||
|
||||
print("[INFO] Reading file content...", sep="")
|
||||
|
||||
while True:
|
||||
line = readOnlyFileDescriptor.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
else:
|
||||
fileContent.append(line)
|
||||
print("[DEBUG] Read line!")
|
||||
|
||||
userTemplate = """
|
||||
|
||||
#begin
|
||||
\"{0}\" = {{
|
||||
isNormalUser = true;
|
||||
hashedPassword = \"{1}\";
|
||||
}};
|
||||
#end
|
||||
""".format(
|
||||
request.headers.get("X-User"), hashedPassword
|
||||
)
|
||||
|
||||
mailUserTemplate = """
|
||||
\"{0}@{2}\" = {{
|
||||
hashedPassword =
|
||||
\"{1}\";
|
||||
catchAll = [ \"{2}\" ];
|
||||
|
||||
sieveScript = ''
|
||||
require [\"fileinto\", \"mailbox\"];
|
||||
if header :contains \"Chat-Version\" \"1.0\"
|
||||
{{
|
||||
fileinto :create \"DeltaChat\";
|
||||
stop;
|
||||
}}
|
||||
'';
|
||||
}};""".format(
|
||||
request.headers.get("X-User"),
|
||||
hashedPassword,
|
||||
request.headers.get("X-Domain"),
|
||||
)
|
||||
|
||||
for line in fileContent:
|
||||
index += 1
|
||||
if line.startswith(" #begin"):
|
||||
print("[DEBUG] Found user configuration snippet match!")
|
||||
print(
|
||||
"[INFO] Writing new user configuration snippet to memory...", sep=""
|
||||
)
|
||||
fileContent.insert(index - 1, userTemplate)
|
||||
print("done")
|
||||
break
|
||||
|
||||
print("[INFO] Writing data from memory to file...", sep="")
|
||||
readWriteFileDescriptor = open("/etc/nixos/users.nix", "w")
|
||||
userConfigurationWriteOperationResult = readWriteFileDescriptor.writelines(
|
||||
fileContent
|
||||
)
|
||||
print("done")
|
||||
|
||||
readOnlyFileDescriptor.close()
|
||||
readWriteFileDescriptor.close()
|
||||
|
||||
print(
|
||||
"[INFO] Opening /etc/nixos/mailserver/system/mailserver.nix.nix for reading...",
|
||||
sep="",
|
||||
)
|
||||
readOnlyFileDescriptor = open("/etc/nixos/mailserver/system/mailserver.nix")
|
||||
print("done")
|
||||
|
||||
fileContent = list()
|
||||
index = int(0)
|
||||
|
||||
while True:
|
||||
line = readOnlyFileDescriptor.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
else:
|
||||
fileContent.append(line)
|
||||
print("[DEBUG] Read line!")
|
||||
|
||||
for line in fileContent:
|
||||
if line.startswith(" loginAccounts = {"):
|
||||
print("[DEBUG] Found mailuser configuration snippet match!")
|
||||
print(
|
||||
"[INFO] Writing new user configuration snippet to memory...", sep=""
|
||||
)
|
||||
fileContent.insert(index + 1, mailUserTemplate)
|
||||
print("done")
|
||||
break
|
||||
index += 1
|
||||
|
||||
readWriteFileDescriptor = open(
|
||||
"/etc/nixos/mailserver/system/mailserver.nix", "w"
|
||||
)
|
||||
|
||||
mailUserConfigurationWriteOperationResult = readWriteFileDescriptor.writelines(
|
||||
fileContent
|
||||
)
|
||||
|
||||
return {
|
||||
"result": 0,
|
||||
"descriptor0": userConfigurationWriteOperationResult,
|
||||
"descriptor1": mailUserConfigurationWriteOperationResult,
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
# Return 400 if username is not provided
|
||||
if request.headers.get("X-User") is None:
|
||||
return {"error": "username is required"}, 400
|
||||
# Return 400 if password is not provided
|
||||
if request.headers.get("X-Password") is None:
|
||||
return {"error": "password is required"}, 400
|
||||
# Check is username passes regex
|
||||
if not re.match(r"^[a-z_][a-z0-9_]+$", request.headers.get("X-User")):
|
||||
return {"error": "username must be alphanumeric"}, 400
|
||||
# Check if username less than 32 characters
|
||||
if len(request.headers.get("X-User")) > 32:
|
||||
return {"error": "username must be less than 32 characters"}, 400
|
||||
# Return 400 if user already exists
|
||||
for user in data["users"]:
|
||||
if user["username"] == request.headers.get("X-User"):
|
||||
return {"error": "User already exists"}, 400
|
||||
if "users" not in data:
|
||||
data["users"] = []
|
||||
data["users"].append(
|
||||
{
|
||||
"username": request.headers.get("X-User"),
|
||||
"hashedPassword": hashedPassword,
|
||||
}
|
||||
)
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {"result": 0}
|
||||
|
||||
def delete(self):
|
||||
user = subprocess.Popen(["userdel", request.headers.get("X-User")])
|
||||
user.communicate()[0]
|
||||
return user.returncode
|
||||
with open("/etc/nixos/userdata/userdata.json", "r+", encoding="utf8") as f:
|
||||
portalocker.lock(f, portalocker.LOCK_EX)
|
||||
try:
|
||||
data = json.load(f)
|
||||
# Return 400 if username is not provided
|
||||
if request.headers.get("X-User") is None:
|
||||
return {"error": "username is required"}, 400
|
||||
# Return 400 if user does not exist
|
||||
for user in data["users"]:
|
||||
if user["username"] == request.headers.get("X-User"):
|
||||
data["users"].remove(user)
|
||||
break
|
||||
else:
|
||||
return {"error": "User does not exist"}, 400
|
||||
|
||||
f.seek(0)
|
||||
json.dump(data, f, indent=4)
|
||||
f.truncate()
|
||||
finally:
|
||||
portalocker.unlock(f)
|
||||
|
||||
return {"result": 0}
|
||||
|
|
Loading…
Reference in a new issue