def getValidUser(self, username, password): if type(username) is not str: l.error("username type is not str") return None if len(username) > USERNAME_MAX: l.error("%s is more that %d characters." % (username, USERNAME_MAX)) return None if type(password) is not str: l.error("password type is not str") return None if not RE_SHA1.match(password): l.error("%s does not match regular expression '%s'." % (password, RE_SHA1.pattern)) return None where = dict(Username=username, Password=password) res = self.xec.select('Users', what='GUID', where=web.db.sqlwhere(where)) try: res = res[0] except IndexError: # This guid did not exist, return the correct type l.warn("Bad password match for user %s" % username) return None return res.GUID
def addUser(self, username, password): if type(username) is not str: l.error("username type is not str.") return None if type(password) is not str: l.error("password type is not str.") return None if len(username) > USERNAME_MAX: l.error('username is greater than %d characters.' % USERNAME_MAX) return None if not RE_SHA1.match(password): l.error("%s does not match regular expression '%s'." % (password, RE_SHA1.pattern)) return None # The guid will be stored in the cookie with the user. guid = str(uuid.uuid4()) try: self.xec.insert('Users', GUID=guid, Username=username, Password=password) except sqlite3.IntegrityError: l.warn("username %s already exists." % username) return None return guid
def getUserG(self, guid): if type(guid) is not str: l.error("guid type is not str") return ( None, None, ) if not RE_UUID.match(guid): l.error("%s does not match regular expression '%s'." % (guid, RE_UUID.pattern)) return ( None, None, ) where = dict(GUID=guid) res = self.xec.select('Users', what='Username,Password', where=web.db.sqlwhere(where)) try: res = res[0] except IndexError: # This guid did not exist, return the correct type l.warn("guid %s does not exist." % guid) return ( None, None, ) return (res.Username, res.Password)
def getUser(self, username): if type(username) is not str: l.error("username type is not str") return ( None, None, ) if len(username) > USERNAME_MAX: l.error("%s is greater than %d characters." % (username, USERNAME_MAX)) return ( None, None, ) where = dict(Username=username) res = self.xec.select('Users', what='GUID,Password', where=web.db.sqlwhere(where)) try: res = res[0] except IndexError: # This username did not exist, return the correct type l.warn("username %s does not exist." % username) return ( None, None, ) return (res.GUID, res.Password)
def POST(self): l.info('POST logon') i = web.input() if 'username' not in i: l.error('username field required for POST') return logon_redirect() if 'password' not in i: l.error('password field required for POST') return logon_redirect() # XXX: validate inputs username = str(i['username']) password = str(i['password']) if not RE_USERNAME.match(username): l.warn('username does not match %s' % RE_USERNAME.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed username') if not RE_PASSWORD.match(password): l.warn('password does not match %s' % RE_PASSWORD.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed password') h = hashlib.sha1() # hash password h.update(password) # hash with salt h.update(username) db_guid = web.d.getValidUser(username, h.hexdigest()) if not db_guid: # invalid credentials return logon_redirect() create_cookie(str(db_guid), username) return web.seeother('/')
def feed_clean(file_name: str) -> None: """cleans a podcast feed's folder""" feed_file_folder: str = os.path.split(file_name)[0] xml_element_tree: ET.ElementTree = ET.parse(file_name) xml_root: ET.Element = xml_element_tree.getroot() # loop modified objects: enclosure_file_names: MutableSet[str] = set() enclosure_relative_folder: Optional[str] = None for item in xml_root.findall("./channel/item/enclosure"): enclosure_url: str = item.attrib["url"] url_parse_result: ParseResult = urlparse(enclosure_url) if enclosure_relative_folder is None: enclosure_relative_folder = os.path.dirname(url_parse_result.path) enclosure_file_names.add(os.path.basename(url_parse_result.path)) if enclosure_relative_folder is None: l.warn(f"No enclosures in feed file {file_name}") return enclosure_abs_folder = os.path.join(feed_file_folder, enclosure_relative_folder[1:]) existing_file_names: List[str] = os.listdir(enclosure_abs_folder) files_to_delete: List[str] = [ os.path.join(enclosure_abs_folder, f) for f in existing_file_names if f not in enclosure_file_names ] l.info( f"Feed file {file_name} - deleting {len(files_to_delete)} out of {len(existing_file_names)} files" ) for file_name in files_to_delete: os.unlink(file_name)
def POST(self): l.info('POST adduser') i = web.input() if 'username' not in i: l.error('username field required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing username') if 'password' not in i: l.error('password field required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing password') if 'password2' not in i: l.error('password2 field required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing password2') if 'recaptcha_challenge_field' not in i: l.error('recaptcha_challenge_field required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing recaptcha_challenge_field') if 'recaptcha_response_field' not in i: l.error('recaptcha_response_field required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing_recaptcha_response_field') # XXX: validate inputs username = str(i['username']) password = str(i['password']) password2 = str(i['password2']) if password != password2: l.warn("passwords don't match. not creating user.") return render.error(web.ctx.fullpath, 'BADREQ', 'password mismatch') if not RE_USERNAME.match(username): l.warn('username does not match %s' % RE_USERNAME.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed username') if not RE_PASSWORD.match(password): l.warn('password does not match %s' % RE_PASSWORD.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed password') challenge = i['recaptcha_challenge_field'] response = i['recaptcha_response_field'] result = captcha.submit(challenge, response, web.captcha_private_key, web.ctx.ip) if result.error_code: l.warn('error validating captcha: %s' % result.error_code) return render.error(web.ctx.fullpath, 'BADREQ', 'bad captcha: %s' % result.error_code) if not result.is_valid: l.warn('invalid captcha') return render.error(web.ctx.fullpath, 'BADREQ', 'bad captcha') h = hashlib.sha1() # hash password h.update(password) # hash with salt h.update(username) l.debug('Creating new user %s' % username) guid = web.d.addUser(username, h.hexdigest()) if not guid: return render.error(web.ctx.fullpath, 'EXISTS', 'username exists') create_cookie(str(guid), username) return web.seeother('/')
def getPrice(self, book): where = dict(Name=book) res = self.xec.select('Books', what='Price', where=web.db.sqlwhere(where)) try: return res[0].Price except IndexError: l.warn('No entry for %s' % book) except AttributeError: l.critical('BUG: no attribute Price')
def POST(self): l.info('POST purchase') if not logged_on(): return logon_redirect() i = web.input() if 'name' not in i: l.error('name required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing name') if 'card' not in i: l.error('card required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing card') if 'ccv' not in i: l.error('ccv required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing ccv') if 'expmonth' not in i: l.error('expmonth required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing expmonth') if 'expyear' not in i: l.error('expyear required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing expyear') if 'book' not in i: l.error('book required for POST') return render.error(web.ctx.fullpath, 'BADREQ', 'missing book') name = i['name'] card = i['card'] book = i['book'] if not RE_NAME.match(name): l.warn('name does not match %s' % RE_NAME.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed name') if not RE_CARDNO.match(card): l.warn('name does not match %s' % RE_CARDNO.pattern) return render.error(web.ctx.fullpath, 'BADREQ', 'malformed card') price = web.d.getPrice(book) l.critical("getting cookie") serial = web.cookies().get(COOKIE_NAME) l.critical("got serial") user = session.cookie.getData(serial) l.critical("got cookie") return render.purchase(user, name, card, book, price)
def setData(self, cookie, data): if not self.isValid(cookie): l.warn("SECURITY ALERT: Setting data on invalid cookie.") (user, expiration, _, _) = self.deserialize(cookie) return self.serialize(user, expiration, data)
def setExpiration(self, cookie, expiration): if not self.isValid(cookie): l.warn("SECURITY ALERT: Setting expiration on invalid cookie.") (user, _, ciphertext, _) = self.deserialize(cookie) plaintext = self.getData(cookie) return self.serialize(user, expiration, plaintext)