def load(self): """ We load the data from the key itself instead of fetching from some external data store. Opposite of _get_session_key(), raises BadSignature if signature fails. $ echo '_json_formatted_' | openssl aes-256-cbc -a -k _passphrase_ -p salt=... key=... iv=... _full_encrypted_ """ session_data = {} try: session_data = json.loads(crypt.decrypt(self.session_key, passphrase=settings.DJAODJIN_SECRET_KEY)) # We have been able to decode the session data, let's # create Users and session keys expected by Django # contrib.auth backend. if 'username' in session_data: user = ProxyUserBackend().authenticate(session_data['username']) session_data[SESSION_KEY] = user.id session_data[BACKEND_SESSION_KEY] \ = 'deployutils.backends.auth.ProxyUserBackend' except (IndexError, TypeError, ValueError) as _: # Incorrect padding in b64decode, incorrect block size in AES, # incorrect PKCS#5 padding or malformed json will end-up here. raise PermissionDenied("Cannot decode session") return session_data
def handle(self, *args, **options): app_name = options['app_name'] passphrase = getpass.getpass('Passphrase:') conn = boto.connect_s3() bucket = conn.get_bucket(options['bucket']) for confname in args: content = None key = bucket.get_key('%s/%s' % (app_name, confname)) encrypted = key.get_contents_as_string() content = crypt.decrypt(encrypted, passphrase) with open(confname, 'w') as conffile: conffile.write(content)
def get_email_host_password(self, passphrase=None): if not passphrase: passphrase = settings.SECRET_KEY return decrypt(self.email_host_password, passphrase=passphrase)
def load_config(confname, module, app_name, prefix='etc', verbose=False, s3_bucket=None, passphrase=None): """ Given a path to a file, parse its lines in ini-like format, and then set them in the current namespace. Quiet by default. Set verbose to True to see the absolute path to the config files printed on stderr. """ from deployutils import crypt # prevent pip install to break. content = None if s3_bucket: try: import boto bucket_name = s3_bucket try: conn = boto.connect_s3() bucket = conn.get_bucket(bucket_name) key = bucket.get_key('%s/%s' % (app_name, confname)) content = key.get_contents_as_string() if verbose: sys.stderr.write( "config loaded from 's3://%s/%s'\n" % ( bucket_name, key.name)) except (boto.exception.NoAuthHandlerFound, boto.exception.S3ResponseError) as _: pass except ImportError: pass # We cannot find a deployutils S3 bucket. Let's look on the filesystem. if not content: confpath = locate_config( confname, app_name, prefix=prefix, verbose=verbose) if confpath: with open(confpath, 'rb') as conffile: content = conffile.read() if content: if passphrase: lines = crypt.decrypt(content, passphrase).split('\n') else: lines = content.split('\n') # We used to parse the file line by line. Once Django 1.5 # introduced ALLOWED_HOSTS (a tuple that definitely belongs # to the site.conf set), we had no choice other than resort # to eval(value, {}, {}). # We are not resorting to import conf module yet but that # might be necessary once we use dictionary configs for some # of the apps... # todo: consider using something like ConfigObj for this: # http://www.voidspace.org.uk/python/configobj.html for line in lines: if not line.startswith('#'): look = re.match(r'(\w+)\s*=\s*(.*)', line) if look: if 'LOCALSTATEDIR' in look.group(2): value = look.group(2) \ % {'LOCALSTATEDIR': module.BASE_DIR + '/var'} else: value = look.group(2) try: #pylint:disable=eval-used setattr(module, look.group(1).upper(), eval(value, {}, {})) except StandardError: raise if hasattr(module, 'LOG_FILE'): for pathname in [module.LOG_FILE]: try: if not os.path.exists(pathname): if not os.path.exists(os.path.dirname(pathname)): os.makedirs(os.path.dirname(pathname)) with open(pathname, 'w') as _: pass # touch file sys.stderr.write('logging app messages in %s\n' % pathname) except OSError: sys.stderr.write( 'warning: permission denied on %s\n' % pathname)