You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

207 rivejä
5.9 KiB

  1. from fastapi import APIRouter, HTTPException
  2. from fastapi.param_functions import Depends
  3. from fastapi.security import OAuth2PasswordRequestForm
  4. from fastapi_login.exceptions import InvalidCredentialsException
  5. import xml.dom.minidom
  6. import xml.etree.ElementTree as ET
  7. from binascii import unhexlify
  8. from ldap3.protocol.formatters.formatters import format_sid
  9. import argparse
  10. import json
  11. import ldap3
  12. import logging
  13. import os
  14. import ssl
  15. import sys
  16. import hashlib
  17. import binascii
  18. from datetime import datetime, timedelta
  19. import subprocess
  20. from typing import List
  21. #from db import get_session
  22. from core.actions import get_user_by_name
  23. from core.security import manager
  24. from core.ldap import LDAPConsole
  25. from security import get_current_user
  26. from models.httpresponse import httpResponse400, httpResponse200, httpResponse500
  27. from models.mnuser import mnuser, post_mnuser, mnuser_groups
  28. router = APIRouter(
  29. prefix="/majornet"
  30. )
  31. MNUSERS_XML_PATH = os.getenv(
  32. "MNUSERS_XML_PATH",
  33. os.getenv("MNUSERS_XML", "/conf/etc/useradmin/mnusers.xml"),
  34. )
  35. def cast_to_dict(cid):
  36. out = {}
  37. for key, value in cid.items():
  38. if type(value) == bytes:
  39. out[key] = str(value)
  40. elif type(value) == list:
  41. if len(value) == 1:
  42. value = value[0]
  43. if type(value) == bytes:
  44. out[key] = str(value)
  45. elif type(value) == datetime:
  46. out[key] = value.strftime('%Y-%m-%d %T')
  47. elif type(value) == timedelta:
  48. # Output format to change
  49. out[key] = value.seconds
  50. else:
  51. out[key] = value
  52. else:
  53. newlist = []
  54. for element in value:
  55. if type(element) == bytes:
  56. newlist.append(str(element))
  57. elif type(element) == datetime:
  58. newlist.append(element.strftime('%Y-%m-%d %T'))
  59. elif type(element) == timedelta:
  60. # Output format to change
  61. newlist.append(element.seconds)
  62. out[key] = newlist
  63. elif type(value) == datetime:
  64. out[key] = value.strftime('%Y-%m-%d %T')
  65. elif type(value) == timedelta:
  66. # Output format to change
  67. out[key] = value.seconds
  68. else:
  69. out[key] = value
  70. return out
  71. def dict_get_paths(d):
  72. paths = []
  73. for key in d.keys():
  74. if type(d[key]) == dict:
  75. paths = [[key]+p for p in dict_get_paths(d[key])]
  76. else:
  77. paths.append([key])
  78. return paths
  79. def dict_path_access(d, path):
  80. for key in path:
  81. if key in d.keys():
  82. d = d[key]
  83. else:
  84. return None
  85. return d
  86. def _element_text(element, tag_name):
  87. child = element.find(tag_name)
  88. if child is None or child.text is None:
  89. return ""
  90. return child.text.strip()
  91. def _split_usergroups(value):
  92. if not value:
  93. return []
  94. return [group.strip() for group in value.split(",") if group.strip()]
  95. def _iter_mnuser_nodes(root):
  96. user_nodes = root.findall(".//useradmin")
  97. if user_nodes:
  98. return user_nodes
  99. return [node for node in root.iter() if node.find("uid") is not None]
  100. def read_mnusers_groups(file_path=MNUSERS_XML_PATH):
  101. tree = ET.parse(file_path)
  102. root = tree.getroot()
  103. users = []
  104. for node in _iter_mnuser_nodes(root):
  105. uid = _element_text(node, "uid")
  106. if not uid:
  107. continue
  108. users.append({
  109. "uid": uid,
  110. "usergroups": _split_usergroups(_element_text(node, "usergroups")),
  111. })
  112. return users
  113. data = {}
  114. import os
  115. USE_LDAP = os.getenv("FASTAPI_LDAP_ENABLED", "false").lower() == "true"
  116. try:
  117. from ..core.ldap import LDAPConsole
  118. except Exception:
  119. LDAPConsole = None
  120. lc = LDAPConsole(debug=True) if (USE_LDAP and LDAPConsole) else None
  121. @router.get(
  122. "/getUsersGroups",
  123. response_model=List[mnuser_groups],
  124. tags=["MajorNet"],
  125. dependencies=[Depends(get_current_user)],
  126. )
  127. async def get_users_groups():
  128. try:
  129. return read_mnusers_groups()
  130. except FileNotFoundError:
  131. raise HTTPException(status_code=404, detail="mnusers.xml not found")
  132. except ET.ParseError:
  133. raise HTTPException(status_code=500, detail="Invalid mnusers.xml")
  134. except OSError:
  135. raise HTTPException(status_code=500, detail="Unable to read mnusers.xml")
  136. @router.get("/users/",tags=["MajorNet"], responses={200: {"model": httpResponse200}, 400: {"model": httpResponse400}, 500: {"model": httpResponse500}})
  137. async def get_majornet_users(current_user= Depends(manager)):
  138. response = lc.queryallusers("ou=users", attributes=['displayName','mail','uid'])
  139. data = {}
  140. for cn in response:
  141. path = cn.split(',')[::-1]
  142. tmp = data
  143. for key in path[:-1]:
  144. if key in tmp.keys():
  145. tmp = tmp[key]
  146. else:
  147. tmp[key] = {}
  148. tmp = tmp[key]
  149. tmp[path[-1]] = cast_to_dict(response[cn])
  150. json_data = json.dumps(data, indent=4)
  151. return data
  152. #,current_user= Depends(manager)
  153. #,current_user: Depends(manager)
  154. # response_model=post_mnuser,
  155. @router.post("/users/add_user/", response_model=post_mnuser, tags=["MajorNet"])
  156. async def majornet_add_user(mnuser:str, mnpasswd:str, mndisplayname:str, mnmail="", mnprofile= "default",current_user= Depends(manager) ):
  157. #print (current_user.username)
  158. #print (mnuser+" "+mnpasswd+" "+mndisplayname+" "+mnprofile)
  159. proc = subprocess.Popen(['perl', '/var/opt/FastAPI/addusr.pl', mnuser, mnpasswd , mndisplayname, mnmail ], stdout=subprocess.PIPE)
  160. stdout_value = proc.communicate()[0]
  161. stdout_value=stdout_value.decode('UTF-8')
  162. response = {"return_code": stdout_value.split(';')[0], "return_str" : stdout_value.split(';')[1] }
  163. return response