def restore_keys(self): """ After being loaded in, re-create out key objects. """ # Restore our master key if self.UserSettings['keys'].get('master') is not None: if 'encryptedprivkey' in self.UserSettings['keys']['master']: self.Keys['master'] = LockedKey( pub=self.UserSettings['keys']['master']['pubkey'], encryptedprivkey=self.UserSettings['keys']['master'] ['encryptedprivkey']) self.Keys['master'].generated = self.UserSettings['keys'][ 'master']['generated'] self.Keys['master'].expires = self.UserSettings['keys'][ 'master']['expires'] self.server.logger.info("Reconstructed with encryptedprivkey") else: # If we just have a pubkey string, do the best we can. if self.UserSettings['keys']['master'].get('pubkey'): self.Keys['master'] = Key( pub=self.UserSettings['keys']['master']['pubkey']) self.Keys['master'].generated = self.UserSettings['keys'][ 'master'].get('generated') self.Keys['master'].expires = self.UserSettings['keys'][ 'master'].get('expires') self.server.logger.info( "reconstructed user without privkey") else: print("Requested user had no master key.") # Restore any Posted communication keys. for key in self.UserSettings['keys'].get('posted', []): lk = LockedKey(pub=key['pubkey'], encryptedprivkey=key['encryptedprivkey']) lk.generated = key['generated'] lk.expires = key['expires'] self.Keys['posted'].append(lk) # Restore any oneoff communication keys for key in self.UserSettings['keys'].get('secret', []): lk = LockedKey(pub=key['pubkey'], encryptedprivkey=key['encryptedprivkey']) lk.generated = key['generated'] lk.expires = key['expires'] self.Keys['secret'].append(lk)
def generate(self, AllowGuestKey=True, password=None, email=None, username=None): """Create a Tavern user, filling in any missing information for existing users. Only creates keys if asked to. """ # Ensure that these values are filled in. # Either by Saved values, Passed-in values, or by Null objects. # Create a string/immutable version of UserSettings that we can compare # against later to see if anything changed. tmpsettings = str(self.UserSettings) + str(self.Keys) if self.UserSettings.get('username') is None: if username is not None: self.UserSettings['username'] = username else: self.UserSettings['username'] = "******" if self.UserSettings.get('email') is None: if email is not None: self.UserSettings['email'] = email else: self.UserSettings['email'] = "*****@*****.**" if self.UserSettings['status'].get('guest') is None: self.UserSettings['status']['guest'] = True if not 'setpassword' in self.UserSettings['status']: self.UserSettings['status']['setpassword'] = None # If we've been told not to use a GuestKey, make sure we don't have # one. if AllowGuestKey is False and self.server.guestacct is not None: if self.server.guestacct.Keys.get( 'master') is not None and self.Keys.get( 'master') is not None: if self.Keys['master'].pubkey == self.server.guestacct.Keys[ 'master'].pubkey: print("Getting rid of a GuestKey.") self.UserSettings['keys'] = {} self.UserSettings['keys']['master'] = {} self.passkey = None self.Keys = {} self.Keys['posted'] = [] self.Keys['secret'] = [] self.Keys['master'] = None # Ensure we don't somehow end up as an empty, but keyed user.. if isinstance(self.Keys['master'], LockedKey): if self.Keys['master'].pubkey is None: self.Keys['master'] = None # Ensure we have a valid keys, one way or another. # If GuestKey is true, then use the server default accts. # Otherwise, make the keys. if self.Keys.get('master') is None: # Save if we're using the GuestKey or not. if AllowGuestKey: self.Keys = self.server.guestacct.Keys self.UserSettings['status']['guest'] = True else: print("Generating a LockedKey") pulledkey = self.server.unusedkeycache.get(block=True) self.Keys['master'] = LockedKey( encryptedprivkey=pulledkey['encryptedprivkey'], pub=pulledkey['pubkey'], password=pulledkey['password']) self.UserSettings['status']['guest'] = False self.passkey = self.Keys['master'].get_passkey( password=pulledkey['password']) # Ensure we have a valid/current public posted key. if self.UserSettings['status']['guest'] is not True: # Set key to false, disprove assertion later. validcommkey = False # Make sure our Posted keys are in good shape. if len(self.Keys['posted']) > 0: # Sort the keys that we've already posted, highest expires # first. self.Keys['posted'].sort(key=lambda e: (e.expires), reverse=True) # Are we still in the same month we generated the key in? gen_month = datetime.datetime.fromtimestamp( self.Keys['posted'][-1].generated).month gen_year = datetime.datetime.fromtimestamp( self.Keys['posted'][-1].generated).year if gen_year == datetime.datetime.now().year: if gen_month == datetime.datetime.now().month: validcommkey = True # Either we have no key, or an old one. if validcommkey is False: print("Generating new posted key") newkey = LockedKey() newkey.generate(passkey=self.passkey) # We want the key to expire on the last second of NEXT month. # So if it's currently Oct 15, we want the answer Nov31-23:59:59 # This makes it harder to pin down keys by when they were # generated, since it's not based on current time number_of_days_this_month = calendar.monthrange( datetime.datetime.now().year, datetime.datetime.now().month)[1] number_of_days_next_month = calendar.monthrange( datetime.datetime.now().year, datetime.datetime.now().month + 1)[1] two_months = datetime.datetime.now() + datetime.timedelta( days=number_of_days_this_month + number_of_days_next_month) expiresdate = datetime.date(two_months.year, two_months.month, 1) - datetime.timedelta(days=1) expiresdatetime = datetime.datetime.combine( expiresdate, datetime.time.max) expirestamp = calendar.timegm(expiresdatetime.utctimetuple()) newkey.expires = expirestamp self.Keys['posted'].append(newkey) if password is not None and self.passkey is None: self.passkey = self.Keys['master'].get_passkey(password=password) if self.UserSettings.get('time_created') is None: self.UserSettings['time_created'] = int(time.time()) if self.UserSettings.get('display_useragent') is None: self.UserSettings['display_useragent'] = False if self.UserSettings.get('theme') is None: self.UserSettings['theme'] = 'default' if self.UserSettings.get('followedTopics') is None: self.UserSettings['followedTopics'] = [] if self.UserSettings.get('allowembed') is None: self.UserSettings['allowembed'] = 0 if self.UserSettings['followedTopics'] == []: self.followTopic("StarTrek") self.followTopic("Python") self.followTopic("Egypt") self.followTopic("Funny") if self.UserSettings.get('maxposts') is None: self.UserSettings['maxposts'] = 100 if self.UserSettings.get('maxreplies') is None: self.UserSettings['maxreplies'] = 100 # Set Friendlyname to most recent post, or Anonymous for lurkers if self.UserSettings.get('friendlyname') is None: if self.UserSettings['status']['guest'] is False: # They're registered, they may have posted. posts = self.server.getUsersPosts(self.Keys['master'].pubkey) if len(posts) > 0: self.UserSettings['friendlyname'] = posts[0].dict[ 'envelope']['local']['author']['friendlyname'] if self.UserSettings.get('friendlyname') is None: self.UserSettings['friendlyname'] = 'Anonymous' if self.UserSettings.get('include_location') is None: self.UserSettings['include_location'] = False if self.UserSettings.get('ignoreedits') is None: self.UserSettings['ignoreedits'] = False if self.UserSettings.get('author_wordhash') is None: self.UserSettings[ 'author_wordhash'] = self.server.wordlist.wordhash( self.Keys['master'].pubkey) if self.UserSettings.get('author_sha512') is None: if self.UserSettings['status']['guest'] is False: self.UserSettings['author_sha512'] = hashlib.sha512( self.Keys['master'].pubkey.encode('utf-8')).hexdigest() else: self.UserSettings['author_sha512'] = None # Determine if we changed anything without an explicit dirty flag. if tmpsettings == str(self.UserSettings) + str(self.Keys): return False else: return True