def _get_mtime(self): try: return os.stat(self._cache_file).st_mtime except (EnvironmentError, AttributeError) as exc: get_logger("cache").warning( "Unable to get mtime for {}".format(exc)) return 0
def _load(self): get_logger("cache").info("loading cache file {}".format( self._cache_file)) try: with open(self._cache_file) as fd: self._cache = json.load(fd) except (EnvironmentError, ValueError): get_logger("cache").exception("Error loading {}".format( self._cache_file)) else: self._loaded = True
def _refresh(self): try: with open(self._password_file) as fd: password = fd.read().rstrip("\n") except EnvironmentError: get_logger("cache").warning("Unable to read {}".format( self._password_file)) return None con = ldap.initialize(self._ldap_uri) con.simple_bind_s(self._bind_dn, password) ldap_content = {} users = {} groups = con.search_s(self._ldap_base, ldap.SCOPE_SUBTREE, u"(objectClass=posixGroup)") for dn, attrs in groups: usernames = [] groups = [] member_uids = [ member.decode("utf-8").lower() for member in attrs.get("memberUid", []) ] unique_members = [ member.decode("utf-8").lower() for member in attrs.get("uniqueMember", []) ] for member in member_uids: if not member.endswith("$"): usernames.append(member.lower()) for member in unique_members: if member.startswith("cn="): member_uid = str2dn(member)[0][0][1] if "{}$".format(member_uid) not in member_uids: groups.append(member) ldap_content[dn.lower()] = { "usernames": usernames, "groups": groups } groups_with_nested_groups = {} for group_dn in ldap_content: self._nested_groups(group_dn, ldap_content, groups_with_nested_groups) for group_dn, attrs in ldap_content.items(): for user in attrs["usernames"]: groups = users.setdefault(user, set()) groups.update(groups_with_nested_groups[group_dn]) users = dict((user, list(groups)) for user, groups in users.items()) with tempfile.NamedTemporaryFile(mode="w", delete=False) as fd: json.dump(users, fd, sort_keys=True, indent=4) return fd
def _request_umc_get(self, get_path, headers): uri = "http://127.0.0.1/univention/get/{}".format(get_path) body = {"options": {}} try: response = requests.post(uri, json=body, headers=headers) except requests.exceptions.RequestException as exc: get_logger("umc").warning("Exception while getting %s: %s", get_path, exc) return [] else: if response.status_code != 200: get_logger("umc").debug("Status %r while getting %s", response.status_code, get_path) return [] return response.json()[get_path]
def _write_image(self, name, img, dirname): try: name = name.replace( "/", "-" ) # name must not contain / and must be a path which can be accessed via the web! string_buffer = BytesIO(img) suffix = what(string_buffer) or "svg" fname = "/usr/share/univention-portal/icons/%s/%s.%s" % ( dirname, name, suffix) with open(fname, "wb") as fd: fd.write(img) except (EnvironmentError, TypeError, IOError): get_logger("img").exception("Error saving image for %s" % name) else: return "./icons/%s/%s.%s" % ( quote(dirname), quote(name), quote(suffix), )
def refresh(self, reason=None, content=None): if self._check_reason(reason, content=content): get_logger("cache").info("refreshing cache") fd = None try: fd = self._refresh() except Exception: get_logger("cache").exception("Error during refresh") # hopefully, we can still work with an older cache? else: if fd: try: os.makedirs(os.path.dirname(self._cache_file)) except EnvironmentError: pass shutil.move(fd.name, self._cache_file) self._mtime = self._get_mtime() return True return self._file_was_updated()
def _refresh(self): udm_lib = importlib.import_module("univention.udm") try: udm = udm_lib.UDM.machine().version(2) portal = udm.get("portals/portal").get(self._portal_dn) except udm_lib.ConnectionError: get_logger("cache").warning( "Could not establish UDM connection. Is the LDAP server accessible?" ) return None except udm_lib.UnknownModuleType: get_logger("cache").warning( "UDM not up to date? Portal module not found.") return None except udm_lib.NoObject: get_logger("cache").warning("Portal %s not found", self._portal_dn) return None content = {} content["portal"] = self._extract_portal(portal) content["categories"] = categories = self._extract_categories( udm, portal) content["folders"] = folders = self._extract_folders( udm, portal, list(categories.values())) content["entries"] = self._extract_entries(udm, portal, list(categories.values()), list(folders.values())) content["user_links"] = self._extract_user_links(portal) content["menu_links"] = self._extract_menu_links(portal) with tempfile.NamedTemporaryFile(mode="w", delete=False) as fd: json.dump(content, fd, sort_keys=True, indent=4) return fd
def _ask_umc(self, cookies, headers): try: response = requests.get(self.umc_session_url, cookies=cookies, headers=headers) data = response.json() username = data["result"]["username"] except requests.RequestException as e: get_logger("user").error("connection failed: %s" % e) except ValueError: get_logger("user").error("malformed answer!") except KeyError: get_logger("user").warning("session unknown!") else: return username
def _get_username(self, cookies): for cookie in cookies: if cookie.startswith("UMCSessionId"): # UMCSessionId-1234 -> Host: localhost:1234 host_port = cookie[13:] if host_port: host_port = ":{}".format(host_port) break else: get_logger("user").debug("no user given") return None, None headers = {"Host": "localhost" + host_port} get_logger("user").debug("searching user for cookies=%r" % cookies) username = self._ask_umc(cookies, headers) if username is None: get_logger("user").debug("no user found") return None, None else: get_logger("user").debug("found %s" % username) return username.lower(), username