예제 #1
0
	def stop(self,
		# success exit (bool).
		success=True,
		# optional order 1 success message (overwrites success to response.success) (ResponseObject, OutputObject, dict).
		response={},
		# optional order 2 success message (overwrites success to True) (str).
		message=None,
		# optional order 3 message (str).
		error=None,
		# json format (bool).
		json=False,
	):
		if response != {}:
			if response["success"] in [True, "True", "true", "TRUE"]:
				success = True
				message = response["message"]
			else:
				success = False
				error = response["error"]
		if message != None: 
			success = True
			_response_.log(message=message, json=json)
		elif error != None: 
			success = False
			_response_.log(error=error, json=json)
		if success: sys.exit(0)
		else: sys.exit(1)
예제 #2
0
    def create(self):

        # check params.
        response = _response_.parameters.check(
            traceback=self.__traceback__(function="create"),
            parameters={
                "id": self.id,
                "user": self.user,
                "start": self.start_,
            })
        if not response.success: return response

        # checks.
        if self.service.fp.exists():
            return _response_.error(
                f"Service [{self.service.fp.path}] already exists (call service.check() instead)."
            )

        # save.
        _response_.log(
            f"&ORANGE&Root permission&END& required to save changes to [{self.service.fp}].",
            log_level=self.log_level)
        self.service.save(data=self.__create__(), sudo=True)
        self.service.fp.ownership.set("root", sudo=True)
        self.service.fp.permission.set(700, sudo=True)
        if dev0s.defaults.vars.os in ["macos"]:
            os.system("sudo systemctl daemon-reload")

        # handler.
        if self.service.fp.exists():
            return _response_.success(
                f"Successfully created service {self.id}.")
        else:
            return _response_.error(f"Failed to create service {self.id}.")
예제 #3
0
		def check(self, 
			# the passed args to except (list).
			exceptions=[], 
			# json mode (bool).
			json=False,
		):
			exceptions += ["--log-level", "--create-alias", "-v", "--version", "-j", "--json", "--non-interactive"]
			lexecutable = self.executable
			while True:
				if len(lexecutable) > 0 and lexecutable[len(lexecutable)-1] == "/": lexecutable = lexecutable[:-1]
				elif "//" in lexecutable: lexecutable = lexecutable.replace("//","/")
				else: break
			for i in sys.argv:
				if i not in ["", lexecutable] and not Files.exists(i) and (len(i) < 1 or (i[0] == "-")):
					try:
						int(i)
						integer = True
					except: integer = False
					if not integer:
						if i not in exceptions and f" {i}: " not in self.modes_str and f" {i}: " not in self.options_str and f" {i} " not in self.modes_str and f" {i} " not in self.options_str:
							error = f"Argument [{i}] is not a valid mode nor option."
							if json:
								_response_.log(error=error, json=True)
								sys.exit(1)
							else: 
								self.docs(stop=False)
								sys.tracebacklimit = -1 ; sys.traceback_limit = -1
								raise Exceptions.UnknownArgumentError(error)
예제 #4
0
    def __init__(
        self,
        # the path to the directory (str) (#1)
        path=None,
        # root permission required.
        sudo=False,
    ):

        # docs.
        DOCS = {
            "module": "dev0s.database.Database",
            "initialized": False,
            "description": [],
            "chapter": "Database",
        }

        # traceback.
        Traceback.__init__(self, traceback="Database")

        # checks.
        if path == None:
            raise Exceptions.InvalidUsage(self.__traceback__() +
                                          " Define parameter [path].")

        # args.
        self.path = gfp.clean(path)
        self.sudo = sudo

        # sys args.
        self.__cache__ = {}

        # attributes.
        self.dir = self.directory = Directory(self.path)

        # checks.
        if not self.dir.fp.exists(sudo=sudo):
            if self.sudo:
                _response_.log(
                    f"&ORANGE&Root permission&END& required to create database [{self.path}]."
                )
            Files.create(
                str(self.path),
                sudo=self.sudo,
                directory=True,
                permission=700,
                owner=defaults.vars.user,
                group=defaults.vars.group,
            )

        # copy objects.
        self.fp = self.file_path = self.dir.fp
        self.ownership = self.fp.ownership
        self.permission = self.fp.permission

        # copy functions.
        self.join = self.dir.join
        self.subpath = self.dir.subpath
        self.fullpath = self.dir.fullpath
예제 #5
0
 def send_crash(
     self,
     # all optional.
     # option 1: the success message.
     message=None,  # (1)
     args={},  # (2)
     # option 2: the error message.
     error=None,
     # option 3: the response object.
     response=None,
     # save the message/error/response.
     save=False,
     # the active log level (int) (leave None to use self.log_level).
     log_level=None,
     # the required log level for when to print to console (leave None to use _response_.log_level ; default: 0).
     required_log_level=_response_.log_level,
 ):
     if log_level == None: log_level = self.log_level
     msg = None
     if isinstance(message, (str, String)):
         self.__response__ = _response_.success(message,
                                                args,
                                                log_level=-1,
                                                save=False)
         msg = message
     elif isinstance(error, (str, String)):
         self.__response__ = _response_.error(error,
                                              log_level=-1,
                                              save=False)
         msg = error
     elif isinstance(response, ResponseObject):
         self.__response__ = response
         if response["success"]:
             msg = response["message"]
         else:
             msg = response["error"]
     #else:
     #	raise Exceptions.InvalidUsage("Define one of the following parameters: [message:str, error:str, response:ResponseObject].")
     self.__status__ = "crashed"
     if msg != None and log_level >= required_log_level or save:
         _response_.log(response=self.__response__,
                        save=save,
                        log_level=log_level,
                        required_log_level=required_log_level)
     return self.__response__
예제 #6
0
 def log(
     self,
     # option 1:
     # the message (#1 param).
     message=None,
     # option 2:
     # the error.
     error=None,
     # option 3:
     # the response dict (leave message None to use).
     response={},
     # print the response as json.
     json=JSON,
     # optionals:
     # the active log level (leave None to use self.log_level).
     log_level=None,
     # the required log level for when printed to console.
     required_log_level=0,
     # save to log file.
     save=False,
     # save errors always (for options 2 & 3 only).
     save_errors=None,
     # the log mode (leave None for default).
     mode=None,
 ):
     if log_level == None: log_level = self.log_level
     return _response_.log(
         # option 1:
         # the message (#1 param).
         message=message,
         # option 2:
         # the error.
         error=error,
         # option 3:
         # the response dict (leave message None to use).
         response=response,
         # print the response as json.
         json=json,
         # optionals:
         # the active log level.
         log_level=log_level,
         # the required log level for when printed to console (leave None to use self.log_level).
         required_log_level=required_log_level,
         # save to log file.
         save=save,
         # save errors always (for options 2 & 3 only).
         save_errors=save_errors,
         # the log mode (leave None for default).
         mode=mode,
     )
예제 #7
0
    def check(self):

        # check params.
        response = _response_.parameters.check(
            traceback=self.__traceback__(function="check"),
            parameters={
                "id": self.id,
                "user": self.user,
                "start": self.start_,
            })
        if not response.success: return response

        # checks.
        if not self.service.fp.exists():
            return self.create()

        # save.
        self.service.load(sudo=True)
        data = self.__create__()
        if self.service.data != data:
            _response_.log(
                f"&ORANGE&Root permission&END& required to save changes to [{self.service.fp}].",
                log_level=self.log_level)
            self.service.save(data=data, sudo=True)
            os.system("sudo systemctl daemon-reload")

        # always set permissions.
        self.service.fp.ownership.set("root", sudo=True)
        self.service.fp.permission.set(700, sudo=True)

        # handler.
        if self.service.fp.exists():
            return _response_.success(
                f"Successfully checked service {self.id}.")
        else:
            return _response_.error(f"Failed to check service {self.id}.")
예제 #8
0
		def get(self, 
			# the argument id (str) (example: --path).
			argument, 
			# whether the argument is required or not (bool).
			required=True, 
			# the plus index (int).
			index=1, 
			# the argument id count index (int).
			count=1, 
			# the value format (str, list) (example: formats=[str].
			format="*",
			# pack multiple into tuple (bool).
			pack=True, 
			# default value when empty (bool, int, float, str, dict, list).
			default=None, 
			# docs chapter (str).
			chapter=None, 
			# docs mode (str).
			mode=None, 
			# json mode (bool).
			json=False,
			# overwrite default notes (dict).
			notes=None,
		):

			# check & clean format.
			def clean_string(string="", remove_first_space=False, remove_last_space=False):
				while True:
					if string in [str, bool, int, float, dict, list, object, tuple]: break
					elif remove_first_space and len(string) > 0 and string[0] == " ": string = string[1:]
					elif remove_last_space and len(string) > 0 and string[len(string)-1] == " ": string = string[:-1]
					else: break
				return string
			def clean_array(array=["x", "y"] or "x,y", remove_first_space=False, remove_last_space=False):
				if isinstance(array, str): 
					array = array.split(",")
				new = []
				for i in array: new.append(clean_string(i, remove_first_space=remove_first_space, remove_last_space=remove_last_space))
				return new
			def clean_dict(dictionary={} or "x:0,y:1"):
				if isinstance(dictionary, str): dictionary = clean_array(dict.split(","), remove_first_space=True, remove_last_space=True)
				if isinstance(dictionary, list):
					new = {}
					for key in dictionary:
						new[clean_string(key, remove_first_space=remove_first_space, remove_last_space=remove_last_space)] = clean_string(value, remove_first_space=remove_first_space, remove_last_space=remove_last_space)
					return new
				elif isinstance(dictionary, dict):
					new = {}
					for key,value in dictionary.items():
						new[clean_string(key, remove_first_space=remove_first_space, remove_last_space=remove_last_space)] = clean_string(value, remove_first_space=remove_first_space, remove_last_space=remove_last_space)
					return new
			if not isinstance(format, list):
				if format not in [str, bool, int, float, dict, list, object, tuple]:
					try:
						format = format.split(",")
					except: 
						format = [format]
				else:
					format = [format]
			if "*" not in format:
				l = []
				for i in clean_array(format, remove_first_space=True, remove_last_space=True):
					if i not in [
						str, "str", "string",
						bool, "bool", "boolean",
						int, "int", "integer",
						float, "float", "double",
						dict, "dict", "json", "dictionary",
						list, "list", "array",
						object, "object", "obj",
						tuple, "tuple",
					]:
						format_error = f"""Specified an invalid format type [{i}], valid formats: {str([str, bool, int, float, tuple, dict, list, object]).replace("'",'')}."""
						if json:
							_response_.log(error=empty_error, json=True)
							sys.exit(1)
						else:
							self.docs(stop=False, chapter=chapter, mode=mode, notes=notes)
							sys.tracebacklimit = -1 ; sys.traceback_limit = -1
							raise Exceptions.InvalidFormatError(invalid_format_error)

					if i in [str, "str", "string"]: i = str
					if i in [bool, "bool", "boolean"]: i = int
					if i in [int, "int", "integer"]: i = int
					if i in [float, "float", "double"]: i = float
					if i in [dict, "dict", "json", "dictionary"]: i = dict
					if i in [list, "list", "array"]: i = list
					if i in [object, "object", "obj"]: i = object
					if i in [tuple, "tuple"]: i = tuple
					l.append(i)
				format = l

			# handle string.
			if isinstance(argument, str):
				
				# set error msg.
				if index == 1:
					empty_error = f"Define argument [{argument}]."
				else:
					empty_error = f"Define argument [{argument}] (index: {index})."

				# check presence.
				if argument not in sys.argv:
					if required:
						if json:
							_response_.log(error=empty_error, json=True)
							sys.exit(1)
						else:
							self.docs(stop=False, chapter=chapter, mode=mode, notes=notes)
							sys.tracebacklimit = -1 ; sys.traceback_limit = -1
							raise Exceptions.EmptyArgumentError(empty_error)
					else: return default

				# retrieve.
				y, c = 0, 0
				for x in sys.argv:
					# get value.
					failed = False
					try:
						if x == argument: 
							c += 1
							if c == count:
								value = sys.argv[y+index]
								# check format.
								if "*" not in format:
									x_format = Formats.get(value, serialize=False)
									error = False
									if x_format == str and int in format:
										try:
											value = int(value)
										except: error = True
									if x_format == str and bool in format:
										try:
											if value in ["true", True, "True", "TRUE"]:
												value = True
											else: 
												value = False
										except: error = True
									if x_format == str and float in format:
										try:
											value = float(value)
										except: error = True
									if x_format == str and list in format:
										try:
											value = clean_array(value, remove_first_space=True, remove_last_space=True)
										except: error = True
									if x_format == str and dict in format:
										try:
											value = clean_dict(value, remove_first_space=True, remove_last_space=True)
										except: error = True
									x_format = Formats.get(value, serialize=False)
									if error or x_format not in format:
										format_error = f"""Provided an incorrect [{argument}] format: [{value}:{x_format}], valid format options: {str(format).replace("'",'')}."""
										if json:
											_response_.log(error=format_error, json=True)
											sys.exit(1)
										else:
											self.docs(stop=False, chapter=chapter, mode=mode, notes=notes)
											sys.tracebacklimit = -1 ; sys.traceback_limit = -1
											raise Exceptions.ArgumentFormatError(format_error)
								return value
					except IndexError: failed = True
					# not present.
					if failed:
						if required:
							if json:
								_response_.log(error=empty_error, json=True)
								sys.exit(1)
							else:
								self.docs(stop=False, chapter=chapter, mode=mode, notes=notes)
								sys.tracebacklimit = -1 ; sys.traceback_limit = -1
								raise Exceptions.EmptyArgumentError(empty_error)
						else: return default
					y += 1

				# should not happen.
				if required:
					if json:
						_response_.log(error=empty_error, json=True)
						sys.exit(1)
					else:
						self.docs(stop=False, chapter=chapter, mode=mode, notes=notes)
						sys.tracebacklimit = -1 ; sys.traceback_limit = -1
						raise Exceptions.EmptyArgumentError(empty_error)
				else: return default

			else:
				if pack:
					arguments = []
					for i in argument: 
						arguments.append(self.get(i, required=required, index=index,default=default, mode=mode, chapter=chapter, notes=notes, json=json, count=count))
					return arguments	
				else:
					for i in argument: 
						a = self.get(i, required=required, index=index,default=default, mode=mode, chapter=chapter, notes=notes, json=json, count=count)
						if a != default: return a
					return default
예제 #9
0
    def activate(
        self,
        # the key's passphrase (optional to retrieve from webserver) (str).
        passphrase=None,
        # interactive (optional)
        interactive=None,
    ):
        if passphrase == None: passphrase = self.passphrase
        if interactive == None: interactive = self.interactive
        new = False
        if passphrase in [False, None, "", "null", "None", "none"]:

            # check webserver.
            if not self.webserver.running:
                if not interactive:
                    return _response_.error(
                        f"{self.traceback}: The webserver is not running.")
                else:
                    if defaults.options.log_level >= 1:
                        _response_.log(
                            f"{ALIAS}: forking {self.id} webserver.")
                    response = self.webserver.fork()
                    if not response.success: return response

            # get pass.
            response, passphrase = self.webserver.get(group="passphrases",
                                                      id="master"), None
            if not response.success and "There is no data cached for" not in response[
                    "error"]:
                return response
            elif response["success"]:
                passphrase = response["data"]
            if passphrase in [False, None, "", "null", "None", "none"]:
                if not interactive:
                    return _response_.error(
                        self.__traceback__(function="activate") +
                        ": Define parameter [passphrase].")
                else:
                    new = True
                    passphrase = getpass.getpass(
                        f"Enter the passphrase of the {self.id} encryption:")

        # activate.
        self.encryption.rsa.passphrase = passphrase
        response = self.encryption.load_keys()
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while activating the {self.id} encryption: {response['error']}"
            )
        self.passphrase = passphrase
        self.db.aes.rsa.passphrase = passphrase
        response = self.db.activate()
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while activating the encrypted cache: {response['error']}"
            )

        # chache.
        if new:
            response = self.webserver.set(group="passphrases",
                                          id="master",
                                          data=passphrase)
            if not response["success"]:
                return _response_.error(
                    f"Encoutered an error while caching the passphrase (#2): {response['error']}"
                )

        # handler.
        return _response_.success("Successfully activated the encryption.")
예제 #10
0
    def __init__(
        self,
        # the encryption & webserver's id (str).
        id="dev0s-agent",
        # the path to the encrypted database (str, String, FilePath).
        database=None,
        # the webserver's host (str).
        host="127.0.0.1",
        # the webserver's port (int).
        port=56000,
        # the path to the private key / the raw private key (str).
        private_key=None,
        # the path to the public key / the raw public key (str).
        public_key=None,
        # the passphrase (optional to prompt) (str).
        passphrase=None,
        # the encryption key in memory only (enable when you passed the private_key & public_key in raw format and the file path) (bool).
        memory=False,
        # the interactive mode (prompt for password) (bool).
        interactive=True,
        # the object traceback (str).
        traceback="dev0s.encryption.Agent",
    ):

        # docs.
        DOCS = {
            "module": "dev0s.encryption.Agent",
            "initialized": False,
            "description": [],
            "chapter": "Encryption",
        }

        # traceback.
        Traceback.__init__(self, traceback=traceback)

        # checks.
        response = _response_.parameters.check(
            traceback=self.__traceback__(),
            parameters={
                "id:str,String": id,
                "database:str,String,FilePath": database,
                "host:str,String": host,
                "port:str,String,int,Integer": port,
                "private_key:str,String,FilePath": private_key,
                "public_key:str,String,FilePath": public_key,
                #"passphrase:str,String":passphrase,
                "memory:bool,Boolean": memory,
                "interactive:bool,Boolean": interactive,
                "traceback:str,String": traceback,
            })
        if not response.success: response.crash()

        # check instances.
        if not Files.exists(str(database)):
            _response_.log(
                f"{color.orange}Root permission{color.end} required to create database [{database}]."
            )
            Files.create(str(database),
                         sudo=True,
                         permission=700,
                         owner=defaults.vars.owner,
                         group=defaults.vars.group,
                         directory=True)

        # init.
        self.id = str(id)
        self.host = str(host)
        self.port = int(port)
        self.private_key = private_key
        self.public_key = public_key
        self.memory = bool(memory)
        self.passphrase = passphrase
        self.interactive = bool(interactive)
        self.db_path = str(database)

        # vars.
        self._activated = False

        # objects.
        self.webserver = _database_.WebServer(
            id=self.id,
            host=self.host,
            port=self.port,
        )
        self.aes = self.encryption = aes.AsymmetricAES(
            public_key=self.public_key,
            private_key=self.private_key,
            passphrase=self.passphrase,
            memory=self.memory,
        )
        self.db = self.database = aes.Database(path=str(self.db_path),
                                               aes=self.encryption)
예제 #11
0
    def generate(
            self,
            # the passphrase (optional to prompt) (str).
            passphrase=None,
            # the verify passphrase (optional).
            verify_passphrase=None,
            # interactive (optional).
            interactive=None):

        # checks.
        if passphrase == None: passphrase = self.passphrase
        if interactive == None: interactive = self.interactive
        if passphrase == None:
            if not interactive:
                return _response_.error(
                    self.__traceback__(function="generate") +
                    ": Define parameter [passphrase].")
            else:
                passphrase = getpass.getpass(
                    f"Enter the passphrase of the {self.id} encryption:")
        elif len(passphrase) < 8:
            return _response_.error(
                "The passphrase must contain at least 8 characters.")
        elif passphrase.lower() == passphrase:
            return _response_.error(
                "The passphrase must contain capital characters.")
        elif (interactive
              and passphrase != getpass.getpass("Enter the same passphrase:")
              ) or (verify_passphrase != None
                    and passphrase != verify_passphrase):
            return _response_.error(
                "The passphrase must contain at least 8 characters.")

        # check webserver.
        if not self.webserver.running:
            #if not interactive:
            #	return _response_.error(f"{self.traceback}: The webserver is not running.")
            #else:
            if defaults.options.log_level >= 1:
                _response_.log(f"{ALIAS}: forking {self.id} webserver.")
            response = self.webserver.fork()
            if not response.success: return response

        # generate.
        self.encryption.rsa.passphrase = passphrase
        response = self.encryption.generate_keys()
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while generating the master encryption key: {response['error']}"
            )
        self.passphrase = passphrase
        if self.memory:
            self.encryption.rsa.private_key = response.private_key
            self.encryption.rsa.public_key = response.public_key
        response = self.encryption.load_keys()
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while activating the {self.id} encryption: {response['error']}"
            )

        # cache.
        response = self.webserver.set(group="passphrases",
                                      id="master",
                                      data=passphrase)
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while caching the passphrase (#1): {response['error']}"
            )

        # database.
        self.db = aes.Database(path=str(self.db_path), aes=self.encryption)
        response = self.db.activate()
        if not response["success"]:
            return _response_.error(
                f"Encoutered an error while activating the encrypted cache: {response['error']}"
            )

        # hander.
        return _response_.success("Successfully generated the encryption.")