@ -1,35 +1,42 @@
 
		
	
		
			
				import  os  
		
	
		
			
				import  base64  
		
	
		
			
				import  copy  
		
	
		
			
				import  secrets  
		
	
		
			
				
 
		
	
		
			
				import  yaml  
		
	
		
			
				from  cryptography . exceptions  import  AlreadyFinalized  
		
	
		
			
				from  cryptography . exceptions  import  InvalidTag  
		
	
		
			
				from  cryptography . exceptions  import  UnsupportedAlgorithm  
		
	
		
			
				from  cryptography . hazmat . backends  import  default_backend  
		
	
		
			
				from  cryptography . hazmat . primitives  import  hashes  
		
	
		
			
				from  cryptography . hazmat . primitives . ciphers . aead  import  AESGCM  
		
	
		
			
				from  cryptography . hazmat . primitives . kdf . pbkdf2  import  PBKDF2HMAC  
		
	
		
			
				
 
		
	
		
			
				# TODO make the config actually safe, hard-coded encryption password is BAD (but a bit better than plaintext)  
		
	
		
			
				
 
		
	
		
			
				
 
		
	
		
			
				class  ConfigReader :  
		
	
		
			
				
 
		
	
		
			
				    kdf  =  None 
 
		
	
		
			
				    nonce  =  None 
 
		
	
		
			
				
 
		
	
		
			
				    CONFIG_VERSION  =  3 
 
		
	
		
			
				    CONFIG_VERSION  =  4 
 
		
	
		
			
				
 
		
	
		
			
				    def  __init__ ( self ,  root_folder :  str , password :  str  ): 
 
		
	
		
			
				    def  __init__ ( self ,  root_folder :  str : 
 
		
	
		
			
				        if  root_folder  is  None : 
 
		
	
		
			
				            raise  Exception ( " No root folder was defined! " ) 
 
		
	
		
			
				        self . __key  =  None 
 
		
	
		
			
				        self . __aesgcm  =  None 
 
		
	
		
			
				        self . data  =  { } 
 
		
	
		
			
				
 
		
	
		
			
				        self . __password  =  password 
 
		
	
		
			
				        self . __config_location  =  os . path . join ( root_folder ,  " .artnet " ,  " artnet.config " ) 
 
		
	
		
			
				        self . __config_key_location  =  os . path . join ( root_folder ,  " .artnet " ,  " artnet_config.key " ) 
 
		
	
		
			
				
 
		
	
		
			
				        try : 
 
		
	
		
			
				            password  =  self . try_get_config_password ( ) 
 
		
	
		
			
				        except  FileNotFoundError  as  e : 
 
		
	
		
			
				            if  not  os . path . exists ( self . __config_location ) : 
 
		
	
		
			
				                self . generate_config_key_file ( ) 
 
		
	
		
			
				                password  =  self . try_get_config_password ( ) 
 
		
	
		
			
				            else : 
 
		
	
		
			
				                raise  e 
 
		
	
		
			
				
 
		
	
		
			
				
 
		
	
		
			
				        ConfigReader . __create_kdf ( ) 
 
		
	
		
			
				        self . __key  =  ConfigReader . kdf . derive ( bytes ( password . encode ( ' utf-8 ' ) ) ) 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -43,6 +50,35 @@ class ConfigReader:
 
		
	
		
			
				            self . create_default_config ( ) 
 
		
	
		
			
				            self . read_config ( ) 
 
		
	
		
			
				
 
		
	
		
			
				    def  try_get_config_password ( self )  - >  str : 
 
		
	
		
			
				        """ 
 
		
	
		
			
				        Attempts  to  read  the  config  encryption  password  from  the  default  location 
 
		
	
		
			
				        """ 
 
		
	
		
			
				        if  os . path . exists ( self . __config_key_location )  and  os . path . isfile ( self . __config_key_location ) : 
 
		
	
		
			
				            with  open ( self . __config_key_location ,  " r " )  as  file : 
 
		
	
		
			
				                password  =  file . readline ( ) 
 
		
	
		
			
				                file . close ( ) 
 
		
	
		
			
				                return  password 
 
		
	
		
			
				        else : 
 
		
	
		
			
				            raise  FileNotFoundError ( f " The config encryption key file could not be found!  " 
 
		
	
		
			
				                                    f " FileNotFound:  { self . __config_key_location } " ) 
 
		
	
		
			
				
 
		
	
		
			
				    def  generate_config_key_file ( self ) : 
 
		
	
		
			
				        """ 
 
		
	
		
			
				        Tries  to  generate  a  new  pseudo - random  generated  key  file  for  encrypting  the  config  file . 
 
		
	
		
			
				
 
		
	
		
			
				        The  key  is  in  plain  text  and  therefore  not  ideal . 
 
		
	
		
			
				        """ 
 
		
	
		
			
				        if  not  os . path . exists ( self . __config_key_location )  and  not  os . path . exists ( self . __config_location ) : 
 
		
	
		
			
				            with  open ( self . __config_key_location ,  " w " )  as  file : 
 
		
	
		
			
				                file . write ( secrets . token_hex ( 100 ) ) 
 
		
	
		
			
				                file . close ( ) 
 
		
	
		
			
				        else : 
 
		
	
		
			
				            raise  Exception ( " Something went terribly wrong!  " 
 
		
	
		
			
				                            " Tried to create new config key file although the key file or config file aready exists!  " 
 
		
	
		
			
				                            " Perhaps old config? " ) 
 
		
	
		
			
				
 
		
	
		
			
				
 
		
	
		
			
				    def  update_config ( self ) : 
 
		
	
		
			
				        """ 
 
		
	
		
			
				        Update  the  written  config  with  the  local  settings