48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
import asyncio
|
|
import functools
|
|
import json
|
|
import struct
|
|
|
|
|
|
async def get_user_home(name:str):
|
|
# Check args
|
|
if not isinstance(name, str):
|
|
raise TypeError("name have to be a string.")
|
|
|
|
# Find home
|
|
proc = await asyncio.create_subprocess_exec(b"getent", b"passwd", name.encode(), stdout=asyncio.subprocess.PIPE)
|
|
proc_data = proc.communicate()
|
|
if not isinstance(proc_data, tuple):
|
|
raise RuntimeError("Internal value isn't the expected type.")
|
|
if proc.returncode != 0:
|
|
raise RuntimeError("getent didn't work.")
|
|
return proc_data[0].split(":")[6]
|
|
|
|
|
|
async def run_access_socket(path:str, async_callback):
|
|
async def run_func(read, write):
|
|
# Get user id
|
|
socket = write.get_extra_info("socket")
|
|
tmp = socket.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize('3i'))
|
|
tmp = struct.unpack('3i', tmp)[1]
|
|
uid = str(tmp)
|
|
|
|
# Run callback
|
|
await async_callback(read, write, uid)
|
|
await (await asyncio.start_unix_server(run_func, path=path)).serve_forever()
|
|
|
|
|
|
_format_length = struct.Struct(">I")
|
|
def rpc_callback(async_func):
|
|
@functools.wraps(async_func)
|
|
async def wrap_func(read, write, uid):
|
|
while not read.at_eof():
|
|
# Read data
|
|
size = _format_length.unpack(await read.readexactly(_format_length.size))
|
|
data = json.loads((await read.readexactly(size)).decode("UTF-8"))
|
|
|
|
# Callback and return result
|
|
result = json.dumps(await async_func(data, uid)).encode("UTF-8")
|
|
write.write(_format_length.pack(len(result)))
|
|
write.write(result)
|
|
return wrap_func |