def __init__(self, syncer=None, minimal=True): self.syncer = syncer self.minimal = minimal self.event_handler = MyFileSystemEventHandler(syncer=self.syncer) self.observer = Observer(timeout=20) self.paths = [] if minimal: self.paths_minimal()
def __init__(self, ssl_private_key): self._ssl_private_key = ssl_private_key self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( FileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start()
def __init__(self, rmq_mgmt, ssl_public_key): self._rmq_mgmt = rmq_mgmt self._ssl_public_key = ssl_public_key self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( FileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() self._certs = Certs()
def __init__(self, tls_private_key=None, web_secret_key=None): self._tls_private_key = tls_private_key self._web_secret_key = web_secret_key if self._tls_private_key is None and self._web_secret_key is None: raise ValueError("Must have either ssl_private_key or web_secret_key specified!") if self._tls_private_key is not None and self._web_secret_key is not None: raise ValueError("Must use either ssl_private_key or web_secret_key not both!") self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( VolttronHomeFileReloader("web-users.json", self.reload_userdict), get_home() ) self._observer.start()
class FileSystemMonitor: def __init__(self, syncer=None, minimal=True): self.syncer = syncer self.minimal = minimal self.event_handler = MyFileSystemEventHandler(syncer=self.syncer) self.observer = Observer(timeout=20) self.paths = [] if minimal: self.paths_minimal() def _log_info(self, msg): print(" - %s" % msg) def paths_minimal(self): self.paths = [] for item in [ "jumpscaleX_core/JumpscaleCore", "jumpscaleX_core/cmds", "jumpscaleX_core/install", # "jumpscaleX_libs", # "jumpscaleX_threebot", # "jumpscaleX_builders", # "jumpscaleX_libs_extra", # "jumpscaleX_weblibs", ]: self.paths.append( "{DIR_CODE}/github/threefoldtech/%s:/sandbox/code/github/threefoldtech/%s" % (item, item)) def _get_paths(self): if self.paths != []: return self.syncer._get_paths(paths=self.paths) else: return self.syncer._get_paths() def start(self): for item in self._get_paths(): source, dest = item self._log_info("monitor:%s" % source) self.observer.schedule(self.event_handler, source, recursive=True) self.observer.start() self._log_info("WE ARE MONITORING ") try: while True: gevent.time.sleep(1) # print(1) except KeyboardInterrupt: self.observer.stop() self.observer.join() def __str__(self): return "FileSystemMonitor"
def __init__(self, rmq_mgmt=None, ssl_public_key: bytes = None, rpc_caller=None): self._rpc_caller = rpc_caller self._rmq_mgmt = rmq_mgmt self._certs = None if rmq_mgmt is not None: self._certs = Certs() self._pending_auths = None self._denied_auths = None self._approved_auths = None if ssl_public_key is None: self._insecure_mode = True else: self._insecure_mode = False # must have a none value for when we don't have an ssl context available. if ssl_public_key is not None: if isinstance(ssl_public_key, bytes): self._ssl_public_key = ssl_public_key.decode('utf-8') elif isinstance(ssl_public_key, str): self._ssl_public_key = ssl_public_key else: raise ValueError("Invalid type for ssl_public_key") else: self._ssl_public_key = None self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( VolttronHomeFileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() if ssl_public_key is not None: self._certs = Certs()
def test_can_watch_for_changes_with_gevent(): # Given a gevent-based thread that counts stuff and sleeps every second count = 0 def counter(): nonlocal count while True: count += 1 time.sleep(1) counter_thread = Thread(target=counter, daemon=True) counter_thread.start() # And an event handler that gets notified when this file changes events = [] class Handler(FileSystemEventHandler): def on_any_event(self, event): events.append(event) # And an observer that dispatches to that handler try: observer = Observer() observer.schedule(Handler(), rel(".."), recursive=True) observer.start() # When I touch this file subprocess.run(["touch", __file__]) # And wait a second time.sleep(1) # Then the counter should have incremented assert count >= 2 # And the event should have been observed assert events == [FileModifiedEvent(__file__)] finally: observer.stop() observer.join()
def __init__(self, tls_private_key=None, tls_public_key=None, web_secret_key=None): self.refresh_token_timeout = 240 # minutes before token expires. TODO: Should this be a setting somewhere? self.access_token_timeout = 15 # minutes before token expires. TODO: Should this be a setting somewhere? self._tls_private_key = tls_private_key self._tls_public_key = tls_public_key self._web_secret_key = web_secret_key if self._tls_private_key is None and self._web_secret_key is None: raise ValueError( "Must have either ssl_private_key or web_secret_key specified!" ) if self._tls_private_key is not None and self._web_secret_key is not None: raise ValueError( "Must use either ssl_private_key or web_secret_key not both!") self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( VolttronHomeFileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start()
def watch_file_with_fullpath(fullpath, callback): """Run callback method whenever the file changes Not available on OS X/MacOS. """ dirname, filename = os.path.split(fullpath) _log.info("Adding file watch for %s", fullpath) _observer = Observer() _observer.schedule(AbsolutePathFileReloader(fullpath, callback), dirname) _log.info("Added file watch for %s", fullpath) _observer.start()
def watch_file(fullpath, callback): """Run callback method whenever the file changes Not available on OS X/MacOS. """ dirname, filename = os.path.split(fullpath) _log.info("Adding file watch for %s dirname=%s, filename=%s", fullpath, get_home(), filename) observer = Observer() observer.schedule(VolttronHomeFileReloader(filename, callback), path=get_home()) observer.start() _log.info("Added file watch for %s", fullpath)
class AuthenticateEndpoints(object): def __init__(self, ssl_private_key): self._ssl_private_key = ssl_private_key self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( FileReloader("web-users.json", self.reload_userdict), get_home() ) self._observer.start() def reload_userdict(self): webuserpath = os.path.join(get_home(), 'web-users.json') self._userdict = PersistentDict(webuserpath) def get_routes(self): """ Returns a list of tuples with the routes for authentication. Tuple should have the following: - regular expression for calling the endpoint - 'callable' keyword specifying that a method is being specified - the method that should be used to call when the regular expression matches code: return [ (re.compile('^/csr/request_new$'), 'callable', self._csr_request_new) ] :return: """ return [ (re.compile('^/authenticate'), 'callable', self.get_auth_token) ] def get_auth_token(self, env, data): """ Creates an authentication token to be returned to the caller. The response will be a text/plain encoded user :param env: :param data: :return: """ if env.get('REQUEST_METHOD') != 'POST': _log.warning("Authentication must use POST request.") return Response('', status='401 Unauthorized') assert len(self._userdict) > 0, "No users in user dictionary, set the master password first!" if not isinstance(data, dict): _log.debug("data is not a dict, decoding") decoded = dict((k, v if len(v) > 1 else v[0]) for k, v in urlparse.parse_qs(data).iteritems()) username = decoded.get('username') password = decoded.get('password') else: username = data.get('username') password = data.get('password') _log.debug("Username is: {}".format(username)) error = "" if username is None: error += "Invalid username passed" if not password: error += "Invalid password passed" if error: _log.error("Invalid parameters passed: {}".format(error)) return Response(error, status='401') user = self.__get_user(username, password) if user is None: _log.error("No matching user for passed username: {}".format(username)) return Response('', status='401') encoded = jwt.encode(user, self._ssl_private_key, algorithm='RS256').encode('utf-8') return Response(encoded, '200 OK', content_type='text/plain') def __get_user(self, username, password): """ Retrieve user from the user store based upon username/password The hashed_password will not be returned with the value in the user object. If there is not a username/password that match return None. :param username: :param password: :return: """ user = self._userdict.get(username) if user is not None: hashed_pass = user.get('hashed_password') if hashed_pass and argon2.verify(password, hashed_pass): usr_cpy = user.copy() del usr_cpy['hashed_password'] return usr_cpy return None
class AdminEndpoints(object): def __init__(self, rmq_mgmt, ssl_public_key): self._rmq_mgmt = rmq_mgmt self._ssl_public_key = ssl_public_key self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( FileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() self._certs = Certs() def reload_userdict(self): webuserpath = os.path.join(get_home(), 'web-users.json') self._userdict = PersistentDict(webuserpath) def get_routes(self): """ Returns a list of tuples with the routes for the adminstration endpoints available in it. :return: """ return [(re.compile('^/admin.*'), 'callable', self.admin)] def admin(self, env, data): if len(self._userdict) == 0: if env.get('REQUEST_METHOD') == 'POST': decoded = dict((k, v if len(v) > 1 else v[0]) for k, v in urlparse.parse_qs(data).iteritems()) username = decoded.get('username') pass1 = decoded.get('password1') pass2 = decoded.get('password2') if pass1 == pass2 and pass1 is not None: _log.debug("Setting master password") self.add_user(username, pass1, groups=['admin']) return Response('', status='302', headers={'Location': '/admin/login.html'}) template = template_env(env).get_template('first.html') return Response(template.render()) if 'login.html' in env.get('PATH_INFO') or '/admin/' == env.get( 'PATH_INFO'): template = template_env(env).get_template('login.html') return Response(template.render()) return self.verify_and_dispatch(env, data) def verify_and_dispatch(self, env, data): """ Verify that the user is an admin and dispatch :param env: web environment :param data: data associated with a web form or json/xml request data :return: Response object. """ from volttron.platform.web import get_user_claims, NotAuthorized try: claims = get_user_claims(env) except NotAuthorized: _log.error("Unauthorized user attempted to connect to {}".format( env.get('PATH_INFO'))) return Response('<h1>Unauthorized User</h1>', status="401 Unauthorized") # Make sure we have only admins for viewing this. if 'admin' not in claims.get('groups'): return Response('<h1>Unauthorized User</h1>', status="401 Unauthorized") # Make sure we have only admins for viewing this. if 'admin' not in claims.get('groups'): return Response('<h1>Unauthorized User</h1>', status="401 Unauthorized") path_info = env.get('PATH_INFO') if path_info.startswith('/admin/api/'): return self.__api_endpoint(path_info[len('/admin/api/'):], data) if path_info.endswith('html'): page = path_info.split('/')[-1] try: template = template_env(env).get_template(page) except TemplateNotFound: return Response("<h1>404 Not Found</h1>", status="404 Not Found") if page == 'list_certs.html': html = template.render( certs=self._certs.get_all_cert_subjects()) elif page == 'pending_csrs.html': html = template.render( csrs=self._certs.get_pending_csr_requests()) else: # A template with no params. html = template.render() return Response(html) template = template_env(env).get_template('index.html') resp = template.render() return Response(resp) def __api_endpoint(self, endpoint, data): _log.debug("Doing admin endpoint {}".format(endpoint)) if endpoint == 'certs': response = self.__cert_list_api() elif endpoint == 'pending_csrs': response = self.__pending_csrs_api() elif endpoint.startswith('approve_csr/'): response = self.__approve_csr_api(endpoint.split('/')[1]) elif endpoint.startswith('deny_csr/'): response = self.__deny_csr_api(endpoint.split('/')[1]) elif endpoint.startswith('delete_csr/'): response = self.__delete_csr_api(endpoint.split('/')[1]) else: response = Response( '{"status": "Unknown endpoint {}"}'.format(endpoint), content_type="application/json") return response def __approve_csr_api(self, common_name): try: _log.debug("Creating cert and permissions for user: {}".format( common_name)) self._certs.approve_csr(common_name) permissions = self._rmq_mgmt.get_default_permissions(common_name) self._rmq_mgmt.create_user_with_permissions( common_name, permissions, True) data = dict(status=self._certs.get_csr_status(common_name), cert=self._certs.get_cert_from_csr(common_name)) except ValueError as e: data = dict(status="ERROR", message=e.message) return Response(json.dumps(data), content_type="application/json") def __deny_csr_api(self, common_name): try: self._certs.deny_csr(common_name) data = dict(status="DENIED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) return Response(json.dumps(data), content_type="application/json") def __delete_csr_api(self, common_name): try: self._certs.delete_csr(common_name) data = dict(status="DELETED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) return Response(json.dumps(data), content_type="application/json") def __pending_csrs_api(self): csrs = [c for c in self._certs.get_pending_csr_requests()] return Response(json.dumps(csrs), content_type="application/json") def __cert_list_api(self): subjects = [ dict(common_name=x.common_name) for x in self._certs.get_all_cert_subjects() ] return Response(json.dumps(subjects), content_type="application/json") def add_user(self, username, unencrypted_pw, groups=[], overwrite=False): if self._userdict.get(username): raise ValueError("Already exists!") if groups is None: groups = [] hashed_pass = argon2.hash(unencrypted_pw) self._userdict[username] = dict(hashed_password=hashed_pass, groups=groups) self._userdict.async_sync()
class AuthenticateEndpoints(object): def __init__(self, tls_private_key=None, tls_public_key=None, web_secret_key=None): self.refresh_token_timeout = 240 # minutes before token expires. TODO: Should this be a setting somewhere? self.access_token_timeout = 15 # minutes before token expires. TODO: Should this be a setting somewhere? self._tls_private_key = tls_private_key self._tls_public_key = tls_public_key self._web_secret_key = web_secret_key if self._tls_private_key is None and self._web_secret_key is None: raise ValueError( "Must have either ssl_private_key or web_secret_key specified!" ) if self._tls_private_key is not None and self._web_secret_key is not None: raise ValueError( "Must use either ssl_private_key or web_secret_key not both!") self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( VolttronHomeFileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() def reload_userdict(self): webuserpath = os.path.join(get_home(), 'web-users.json') self._userdict = PersistentDict(webuserpath) def get_routes(self): """ Returns a list of tuples with the routes for authentication. Tuple should have the following: - regular expression for calling the endpoint - 'callable' keyword specifying that a method is being specified - the method that should be used to call when the regular expression matches code: return [ (re.compile('^/csr/request_new$'), 'callable', self._csr_request_new) ] :return: """ return [(re.compile('^/authenticate'), 'callable', self.handle_authenticate)] def handle_authenticate(self, env, data): """ Callback for /authenticate endpoint. Routes request based on HTTP method and returns a text/plain encoded token or error. :param env: :param data: :return: Response """ method = env.get('REQUEST_METHOD') if method == 'POST': response = self.get_auth_tokens(env, data) elif method == 'PUT': response = self.renew_auth_token(env, data) elif method == 'DELETE': response = self.revoke_auth_token(env, data) else: error = f"/authenticate endpoint accepts only POST, PUT, or DELETE methods. Received: {method}" _log.warning(error) return Response(error, status='405 Method Not Allowed', content_type='text/plain') return response def get_auth_tokens(self, env, data): """ Creates an authentication refresh and acccss tokens to be returned to the caller. The response will be a text/plain encoded user. Data should contain: { "username": "******", "password": "******" } :param env: :param data: :return: """ assert len( self._userdict ) > 0, "No users in user dictionary, set the administrator password first!" if not isinstance(data, dict): _log.debug("data is not a dict, decoding") decoded = dict((k, v if len(v) > 1 else v[0]) for k, v in parse_qs(data).items()) username = decoded.get('username') password = decoded.get('password') else: username = data.get('username') password = data.get('password') _log.debug("Username is: {}".format(username)) error = "" if username is None: error += "Invalid username passed" if not password: error += "Invalid password passed" if error: _log.error("Invalid parameters passed: {}".format(error)) return Response(error, status='401') user = self.__get_user(username, password) if user is None: _log.error( "No matching user for passed username: {}".format(username)) return Response('', status='401') access_token, refresh_token = self._get_tokens(user) response = Response(json.dumps({ "refresh_token": refresh_token, "access_token": access_token }), content_type="application/json") return response def _get_tokens(self, claims): now = datetime.utcnow() claims['iat'] = now claims['nbf'] = now claims['exp'] = now + timedelta(minutes=self.access_token_timeout) claims['grant_type'] = 'access_token' algorithm = 'RS256' if self._tls_private_key is not None else 'HS256' encode_key = self._tls_private_key if algorithm == 'RS256' else self._web_secret_key access_token = jwt.encode(claims, encode_key, algorithm=algorithm) claims['exp'] = now + timedelta(minutes=self.refresh_token_timeout) claims['grant_type'] = 'refresh_token' refresh_token = jwt.encode(claims, encode_key, algorithm=algorithm) return access_token.decode('utf-8'), refresh_token.decode('utf8') def renew_auth_token(self, env, data): """ Creates a new authentication access token to be returned to the caller. The response will be a text/plain encoded user. Request should contain: • Content Type: application/json • Authorization: BEARER <jwt_refresh_token> • Body (optional): { "current_access_token": "<jwt_access_token>" } :param env: :param data: :return: """ current_access_token = data.get('current_access_token') from volttron.platform.web import get_bearer, get_user_claim_from_bearer, NotAuthorized try: current_refresh_token = get_bearer(env) claims = get_user_claim_from_bearer( current_refresh_token, web_secret_key=self._web_secret_key, tls_public_key=self._tls_public_key) except NotAuthorized: _log.error("Unauthorized user attempted to connect to {}".format( env.get('PATH_INFO'))) return Response('Unauthorized User', status="401 Unauthorized") except jwt.ExpiredSignatureError: _log.error( "User attempted to connect to {} with an expired signature". format(env.get('PATH_INFO'))) return Response('Unauthorized User', status="401 Unauthorized") if claims.get('grant_type') != 'refresh_token' or not claims.get( 'groups'): return Response('Invalid refresh token.', status="401 Unauthorized") else: # TODO: Consider blacklisting and reissuing refresh tokens also when used. new_access_token, _ = self._get_tokens(claims) if current_access_token: pass # TODO: keep current subscriptions? blacklist old token? return Response(json.dumps({"access_token": new_access_token}), content_type="application/json") def revoke_auth_token(self, env, data): # TODO: Blacklist old token? Immediately close websockets? return Response('DELETE /authenticate is not yet implemented', status='501 Not Implemented', content_type='text/plain') def __get_user(self, username, password): """ Retrieve user from the user store based upon username/password The hashed_password will not be returned with the value in the user object. If there is not a username/password that match return None. :param username: :param password: :return: """ user = self._userdict.get(username) if user is not None: hashed_pass = user.get('hashed_password') if hashed_pass and argon2.verify(password, hashed_pass): usr_cpy = user.copy() del usr_cpy['hashed_password'] return usr_cpy return None
class AdminEndpoints(object): def __init__(self, rmq_mgmt=None, ssl_public_key: bytes = None, rpc_caller=None): self._rpc_caller = rpc_caller self._rmq_mgmt = rmq_mgmt self._pending_auths = None self._denied_auths = None self._approved_auths = None if ssl_public_key is None: self._insecure_mode = True else: self._insecure_mode = False # must have a none value for when we don't have an ssl context available. if ssl_public_key is not None: if isinstance(ssl_public_key, bytes): self._ssl_public_key = ssl_public_key.decode('utf-8') elif isinstance(ssl_public_key, str): self._ssl_public_key = ssl_public_key else: raise ValueError("Invalid type for ssl_public_key") else: self._ssl_public_key = None self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( VolttronHomeFileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() def reload_userdict(self): webuserpath = os.path.join(get_home(), 'web-users.json') self._userdict = PersistentDict(webuserpath, format="json") def get_routes(self): """ Returns a list of tuples with the routes for the administration endpoints available in it. :return: """ return [(re.compile('^/admin.*'), 'callable', self.admin)] def admin(self, env, data): if len(self._userdict) == 0: if env.get('REQUEST_METHOD') == 'POST': decoded = dict((k, v if len(v) > 1 else v[0]) for k, v in parse_qs(data).items()) username = decoded.get('username') pass1 = decoded.get('password1') pass2 = decoded.get('password2') if pass1 == pass2 and pass1 is not None: _log.debug("Setting administrator password") self.add_user(username, pass1, groups=['admin']) return Response('', status='302', headers={'Location': '/admin/login.html'}) template = template_env(env).get_template('first.html') return Response(template.render(), content_type="text/html") if 'login.html' in env.get('PATH_INFO') or '/admin/' == env.get( 'PATH_INFO'): template = template_env(env).get_template('login.html') _log.debug("Login.html: {}".format(env.get('PATH_INFO'))) return Response(template.render(), content_type='text/html') return self.verify_and_dispatch(env, data) def verify_and_dispatch(self, env, data): """ Verify that the user is an admin and dispatch :param env: web environment :param data: data associated with a web form or json/xml request data :return: Response object. """ from volttron.platform.web import get_bearer, NotAuthorized try: claims = self._rpc_caller(PLATFORM_WEB, 'get_user_claims', get_bearer(env)).get() except NotAuthorized: _log.error("Unauthorized user attempted to connect to {}".format( env.get('PATH_INFO'))) return Response('<h1>Unauthorized User</h1>', status="401 Unauthorized") except RemoteError as e: if "ExpiredSignatureError" in e.exc_info["exc_type"]: _log.warning( "Access token has expired! Please re-login to renew.") template = template_env(env).get_template('login.html') _log.debug("Login.html: {}".format(env.get('PATH_INFO'))) return Response(template.render(), content_type='text/html') else: _log.error(e) # Make sure we have only admins for viewing this. if 'admin' not in claims.get('groups'): return Response('<h1>Unauthorized User</h1>', status="401 Unauthorized") path_info = env.get('PATH_INFO') if path_info.startswith('/admin/api/'): return self.__api_endpoint(path_info[len('/admin/api/'):], data) if path_info.endswith('html'): page = path_info.split('/')[-1] try: template = template_env(env).get_template(page) except TemplateNotFound: return Response("<h1>404 Not Found</h1>", status="404 Not Found") if page == 'pending_auth_reqs.html': try: self._pending_auths = self._rpc_caller.call( AUTH, 'get_authorization_pending').get(timeout=2) self._denied_auths = self._rpc_caller.call( AUTH, 'get_authorization_denied').get(timeout=2) self._approved_auths = self._rpc_caller.call( AUTH, 'get_authorization_approved').get(timeout=2) except TimeoutError: self._pending_auths = [] self._denied_auths = [] self._approved_auths = [] # When messagebus is rmq, include pending csrs in the output pending_auth_reqs.html page if self._rmq_mgmt is not None: html = template.render(csrs=self._rpc_caller.call( AUTH, 'get_pending_csrs').get(timeout=4), auths=self._pending_auths, denied_auths=self._denied_auths, approved_auths=self._approved_auths) else: html = template.render(auths=self._pending_auths, denied_auths=self._denied_auths, approved_auths=self._approved_auths) else: # A template with no params. html = template.render() return Response(html) template = template_env(env).get_template('index.html') resp = template.render() return Response(resp) def __api_endpoint(self, endpoint, data): _log.debug("Doing admin endpoint {}".format(endpoint)) if endpoint == 'certs': response = self.__cert_list_api() elif endpoint == 'pending_csrs': response = self.__pending_csrs_api() elif endpoint.startswith('approve_csr/'): response = self.__approve_csr_api(endpoint.split('/')[1]) elif endpoint.startswith('deny_csr/'): response = self.__deny_csr_api(endpoint.split('/')[1]) elif endpoint.startswith('delete_csr/'): response = self.__delete_csr_api(endpoint.split('/')[1]) elif endpoint.startswith('approve_credential/'): response = self.__approve_credential_api(endpoint.split('/')[1]) elif endpoint.startswith('deny_credential/'): response = self.__deny_credential_api(endpoint.split('/')[1]) elif endpoint.startswith('delete_credential/'): response = self.__delete_credential_api(endpoint.split('/')[1]) else: response = Response( '{"status": "Unknown endpoint {}"}'.format(endpoint), content_type="application/json") return response def __approve_csr_api(self, common_name): try: _log.debug("Creating cert and permissions for user: {}".format( common_name)) self._rpc_caller.call(AUTH, 'approve_authorization_failure', common_name).wait(timeout=4) data = dict( status=self._rpc_caller.call(AUTH, "get_pending_csr_status", common_name).get(timeout=2), cert=self._rpc_caller.call(AUTH, "get_pending_csr_cert", common_name).get(timeout=2)) except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __deny_csr_api(self, common_name): try: self._rpc_caller.call(AUTH, 'deny_authorization_failure', common_name).wait(timeout=2) data = dict(status="DENIED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __delete_csr_api(self, common_name): try: self._rpc_caller.call(AUTH, 'delete_authorization_failure', common_name).wait(timeout=2) data = dict(status="DELETED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __pending_csrs_api(self): try: data = self._rpc_caller.call(AUTH, 'get_pending_csrs').get(timeout=4) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __cert_list_api(self): try: data = [ dict(common_name=x.common_name) for x in self._rpc_caller.call( AUTH, "get_all_pending_csr_subjects").get(timeout=2) ] except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __approve_credential_api(self, user_id): try: _log.debug( "Creating credential and permissions for user: {}".format( user_id)) self._rpc_caller.call(AUTH, 'approve_authorization_failure', user_id).wait(timeout=4) data = dict(status='APPROVED', message="The administrator has approved the request") except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __deny_credential_api(self, user_id): try: self._rpc_caller.call(AUTH, 'deny_authorization_failure', user_id).wait(timeout=2) data = dict(status="DENIED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def __delete_credential_api(self, user_id): try: self._rpc_caller.call(AUTH, 'delete_authorization_failure', user_id).wait(timeout=2) data = dict(status="DELETED", message="The administrator has denied the request") except ValueError as e: data = dict(status="ERROR", message=e.message) except TimeoutError as e: data = dict(status="ERROR", message=e.message) return Response(jsonapi.dumps(data), content_type="application/json") def add_user(self, username, unencrypted_pw, groups=None, overwrite=False): if self._userdict.get(username) and not overwrite: raise ValueError( f"The user {username} is already present and overwrite not set to True" ) if groups is None: groups = [] hashed_pass = argon2.hash(unencrypted_pw) self._userdict[username] = dict(hashed_password=hashed_pass, groups=groups) self._userdict.sync()
from threading import Thread logging.basicConfig(level=logging.DEBUG) running = True def printer(): global running logger = logging.getLogger("printer") while running: logger.info("Ping!") time.sleep(1) try: pinger = Thread(target=printer) pinger.start() observer = Observer() observer.schedule(LoggingEventHandler(), ".", recursive=True) observer.start() while True: time.sleep(1) except KeyboardInterrupt: running = False observer.stop() observer.join()
def startFileSystemObservation(): observer = Observer() observer.schedule(CsvProcessingHandler(), environ.get("CRIMES_DATA_DIR", DEFAULT_DATA_DIR), recursive=False) observer.start()