def test_user_create(): user = User('cdent') assert type(user) == User assert user.usersign == 'cdent' user.note = note assert user.note == note user.note = 'bar' assert user.note == 'bar'
def test_users(): userc = User('cdent') userc.set_password('foobar') userc.add_role('ADMIN') userc.note = 'A simple programmer of matter' store.put(userc) userf = User('FND') userf.set_password('I<3whitespace') store.put(userf) user2 = store.get(User('cdent')) assert user2.usersign == userc.usersign assert user2.check_password('foobar') assert user2.list_roles() == userc.list_roles() assert user2.note == userc.note users = list(store.list_users()) assert len(users) == 2 assert ['FND', 'cdent'] == sorted([user.usersign for user in users]) store.delete(User('FND')) users = list(store.list_users()) assert len(users) == 1 py.test.raises(NoUserError, "store.get(User('FND'))")
def establish_user_auth(config, store, host, username): user = User(username) mapping_username = '******' % username mapping_tiddler = Tiddler(mapping_username, 'MAPUSER') mapping_tiddler.fields['mapped_user'] = username try: store.delete(user) except StoreError: pass try: store.delete(mapping_tiddler) except IOError: pass user.add_role('MEMBER') user.note = '{}' store.put(user) ensure_bag('MAPUSER', store) store.put(mapping_tiddler) stamp = datetime.utcnow().strftime('%Y%m%d%H') csrf = gen_nonce(username, host, stamp, config['secret']) cookie = make_cookie('tiddlyweb_user', mapping_username, mac_key=config['secret'], httponly=False) return cookie, csrf
def handle(environ, start_response): """ Handle a posted request for registration. If the provided username is blacklisted, ask them to log in as someone else. Otherwise send closing material with a link to get started. """ pretty_name = environ["tiddlyweb.query"].get("pretty_name", [None])[0] target_role = environ["tiddlyweb.config"].get("register_role", "MEMBER") store = environ["tiddlyweb.store"] username = environ["tiddlyweb.usersign"]["name"] if _blacklisted(environ, username): return _send_start(environ, start_response, message="That user has been blocked") user = User(username) try: user = store.get(user) except NoUserError: pass # is cool if they don't exist yet user.add_role("%s" % target_role) if pretty_name: user.note = pretty_name store.put(user) environ["tiddlyweb.usersign"] = {"name": user.usersign, "roles": user.list_roles()} return _send_finish(environ, start_response)
def handle(environ, start_response): """ Handle a posted request for registration. If the provided username is blacklisted, ask them to log in as someone else. Otherwise send closing material with a link to get started. """ pretty_name = environ['tiddlyweb.query'].get('pretty_name', [None])[0] target_role = environ['tiddlyweb.config'].get('register_role', 'MEMBER') store = environ['tiddlyweb.store'] username = environ['tiddlyweb.usersign']['name'] if _blacklisted(environ, username): return _send_start(environ, start_response, message='That user has been blocked') user = User(username) try: user = store.get(user) except NoUserError: pass # is cool if they don't exist yet user.add_role('%s' % target_role) if pretty_name: user.note = pretty_name store.put(user) environ['tiddlyweb.usersign'] = {'name': user.usersign, 'roles': user.list_roles()} return _send_finish(environ, start_response)
def handle(environ, start_response): """ Handle a posted request for registration. If the provided username is blacklisted, ask them to log in as someone else. Otherwise send closing material with a link to get started. """ pretty_name = environ['tiddlyweb.query'].get('pretty_name', [None])[0] target_role = environ['tiddlyweb.config'].get('register_role', 'MEMBER') store = environ['tiddlyweb.store'] username = environ['tiddlyweb.usersign']['name'] if _blacklisted(environ, username): return _send_start(environ, start_response, message='That user has been blocked') user = User(username) try: user = store.get(user) except NoUserError: pass # is cool if they don't exist yet user.add_role('%s' % target_role) if pretty_name: user.note = pretty_name store.put(user) environ['tiddlyweb.usersign'] = { 'name': user.usersign, 'roles': user.list_roles() } return _send_finish(environ, start_response)
def register(environ, start_response): """ register the user """ config = environ['tiddlyweb.config'] store = environ['tiddlyweb.store'] query = environ['tiddlyweb.query'] try: username = query['login'][0] name = query['name'][0] email = query['email'][0] extra = query['extra'][0] redirect = query['redirect'][0] except (KeyError, ValueError) as exc: raise HTTP400('Incomplete form submission: %s' % exc) announcements = query.get('announcements', [None])[0] user = User(username) try: store.get(user) raise HTTP400('That username is not available.') except StoreError: # we expect and want this pass user.add_role(DEFAULT_ROLE) user.note = simplejson.dumps({ 'registered': time(), 'name': name, 'email': email, 'extra': extra, 'announcements': announcements is not None }) store.put(user) create_wiki(environ, '_%s-data' % username, mode='private', username=username, desc='Data Files', validate=False) create_wiki(environ, '%s-notebook' % username, mode='private', username=username, desc='Private Notebook', validate=False) create_wiki(environ, '%s' % username, mode='protected', username=username, desc='Share Stuff', validate=False) redirect_uri = '%s%s' % (server_base_url(environ), redirect) secret = config['secret'] cookie_age = config.get('cookie_age', None) cookie_header_string = make_cookie('tiddlyweb_user', user.usersign, mac_key=secret, path='/', expires=cookie_age) start_response('303 See Other', [('Set-Cookie', cookie_header_string), ('Content-Type', 'text/plain'), ('Location', str(redirect_uri))]) return [redirect_uri]
def test_users(): userc = User(name) userc.set_password(name) userc.add_role('ADMIN') userc.note = 'A simple programmer of matter' store.put(userc) user2 = store.get(User(name)) assert user2.usersign == userc.usersign assert user2.check_password(name) assert user2.list_roles() == userc.list_roles() assert user2.note == userc.note
def test_delete(): user = User('deleteme') user.note = 'delete me please' store.put(user) stored_user = User('deleteme') stored_user = store.get(stored_user) assert stored_user.note == 'delete me please' deleted_user = User('deleteme') store.delete(deleted_user) py.test.raises(NoUserError, 'store.get(deleted_user)') py.test.raises(NoUserError, 'store.delete(deleted_user)')
def test_delete(): user = User("deleteme") user.note = "delete me please" store.put(user) stored_user = User("deleteme") stored_user = store.get(stored_user) assert stored_user.note == "delete me please" deleted_user = User("deleteme") store.delete(deleted_user) py.test.raises(NoUserError, "store.get(deleted_user)") py.test.raises(NoUserError, "store.delete(deleted_user)")
def new_wiki(environ, start_response): username = environ['tiddlyweb.usersign']['name'] if username == 'GUEST': raise UserRequiredError store = environ['tiddlyweb.store'] length = environ['CONTENT_LENGTH'] content = environ['wsgi.input'].read(int(length)) wikiname = cgi.parse_qs(content).get('wikiname', [''])[0] perms = cgi.parse_qs(content).get('perms', [''])[0] if wikiname: bag = Bag(wikiname) try: bag = store.get(bag) raise HTTP409('The bag already exists') except NoBagError: bag.desc = 'hello' bag.policy.owner = username bag.policy.manage = [username] if perms == 'closed': bag.policy.read = [username] bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authrw': bag.policy.read = ['ANY'] bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] if perms == 'read': bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authw': bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] store.put(bag) recipe = Recipe(wikiname) try: recipe = store.get(recipe) raise HTTP409('That recipe already exists') except NoRecipeError: recipe.desc = 'hello' recipe.policy.owner = username recipe.policy.manage = [username] recipe.set_recipe([[TIDDLYWEB_BAG, ''], [bag.name, '']]) store.put(recipe) user = User(username) note = '' try: user = store.get(user) note = user.note except NoUserError: pass note += '%s\n' % wikiname user.note = note store.put(user) raise HTTP302('%s/spowt/%s' % (server_base_url(environ), urllib.quote(username))) else: raise HTTP409('Missing form data')
def test_make_a_bunch(): for x in xrange(RANGE): bag_name = u'bag%s' % x recipe_name = u'recipe%s' % x tiddler_name = u'tiddler%s' % x recipe_list = [(bag_name, '')] tiddler_text = u'hey ho %s' % x field_name = u'field%s' % x field_name2 = u'fieldone%s' % x tag_name = u'tag%s' % x user_name = u'user%s' % x user_pass = u'pass%s' % x user_note = u'note%s' % x user_roles = [u'rolehold', u'role%s' % x] bag = Bag(bag_name) bag.policy.owner = u'owner%s' % x bag.policy.read = [u'hi%s' % x, u'andextra'] bag.policy.manage = [u'R:hi%s' % x, u'andmanage'] store.put(bag) recipe = Recipe(recipe_name) recipe.policy.owner = u'owner%s' % x recipe.policy.read = [u'hi%s' % x, u'andextra'] recipe.policy.manage = [u'R:hi%s' % x, u'andmanage'] recipe.set_recipe(recipe_list) store.put(recipe) tiddler = Tiddler(tiddler_name, bag_name) tiddler.text = tiddler_text tiddler.fields[field_name] = field_name tiddler.fields[field_name2] = field_name2 tiddler.fields['server.host'] = 'gunky' tiddler.tags = [tag_name] store.put(tiddler) store.put(tiddler) user = User(user_name) user.set_password(user_pass) user.note = user_note for role in user_roles: user.add_role(role) store.put(user) bags = [bag.name for bag in store.list_bags()] recipes = [recipe.name for recipe in store.list_recipes()] users = [user.usersign for user in store.list_users()] assert len(bags) == RANGE assert len(recipes) == RANGE assert len(users) == RANGE for x in xrange(RANGE): bname = 'bag%s' % x rname = 'recipe%s' % x uname = 'user%s' % x assert bname in bags assert rname in recipes assert uname in users tiddler = store.get(Tiddler(u'tiddler0', u'bag0')) assert tiddler.fields[u'field0'] == u'field0' assert tiddler.fields[u'fieldone0'] == u'fieldone0' bag = Bag(u'bag0') bag = store.get(bag) tiddlers = [] for tiddler in store.list_bag_tiddlers(bag): tiddlers.append(store.get(tiddler)) assert len(tiddlers) == 1 assert tiddlers[0].title == 'tiddler0' assert tiddlers[0].fields['field0'] == 'field0' assert tiddlers[0].fields['fieldone0'] == 'fieldone0' assert tiddlers[0].tags == ['tag0'] assert sorted(bag.policy.read) == ['andextra', 'hi0'] assert sorted(bag.policy.manage) == ['R:hi0', u'andmanage'] assert bag.policy.owner == 'owner0' user = User(u'user1') user = store.get(user) assert user.usersign == 'user1' assert user.check_password('pass1') assert user.note == 'note1' assert 'role1' in user.list_roles() assert 'rolehold' in user.list_roles() recipe = Recipe(u'recipe2') recipe = store.get(recipe) assert recipe.name == 'recipe2' bags = [bag_name for bag_name, filter in recipe.get_recipe()] assert len(bags) == 1 assert 'bag2' in bags assert sorted(recipe.policy.read) == ['andextra', 'hi2'] assert sorted(recipe.policy.manage) == ['R:hi2', u'andmanage'] assert recipe.policy.owner == 'owner2' recipe.policy.manage = [u'andmanage'] store.put(recipe) recipe = Recipe(u'recipe2') recipe = store.get(recipe) assert recipe.policy.manage == [u'andmanage'] # delete the above things store.delete(bag) py.test.raises(NoBagError, 'store.delete(bag)') py.test.raises(NoBagError, 'store.get(bag)') store.delete(recipe) py.test.raises(NoRecipeError, 'store.delete(recipe)') py.test.raises(NoRecipeError, 'store.get(recipe)') store.delete(user) py.test.raises(NoUserError, 'store.delete(user)') py.test.raises(NoUserError, 'store.get(user)') tiddler = Tiddler(u'tiddler9', u'bag9') store.get(tiddler) assert tiddler.bag == 'bag9' assert tiddler.text == 'hey ho 9' assert tiddler.tags == ['tag9'] assert tiddler.fields['field9'] == 'field9' assert 'server.host' not in tiddler.fields store.delete(tiddler) py.test.raises(NoTiddlerError, 'store.delete(tiddler)') py.test.raises(NoTiddlerError, 'store.get(tiddler)')
def new_wiki(environ, start_response): username = environ['tiddlyweb.usersign']['name'] if username == 'GUEST': raise UserRequiredError store = environ['tiddlyweb.store'] wikiname = environ['tiddlyweb.query'].get('wikiname', [''])[0] perms = environ['tiddlyweb.query'].get('perms', [''])[0] if wikiname: bag = Bag(wikiname) try: bag = store.get(bag) raise HTTP409('The bag already exists') except NoBagError: bag.desc = 'hello' bag.policy.owner = username bag.policy.manage = [username] if perms == 'closed': bag.policy.read = [username] bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authrw': bag.policy.read = ['ANY'] bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] if perms == 'read': bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authw': bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] store.put(bag) recipe = Recipe(wikiname) try: reicpe = store.get(recipe) raise HTTP409('That recipe already exists') except NoRecipeError: recipe.desc = 'hello' recipe.policy.owner = username recipe.policy.manage = [username] recipe.set_recipe([[TIDDLYWEB_BAG, ''], [bag.name, '']]) store.put(recipe) user = User(username) note = '' try: user = store.get(user) note = user.note if not note: note = '' except NoUserError: pass note += '%s\n' % wikiname user.note = note store.put(user) raise HTTP302('%s/spowt2/%s' % (server_base_url(environ), urllib.quote(username))) else: raise HTTP409('Missing form data')
def test_make_a_bunch(): for x in xrange(RANGE): bag_name = u'bag%s' % x recipe_name = u'recipe%s' % x tiddler_name = u'tiddler%s' % x recipe_list = [(bag_name, '')] tiddler_text = u'hey ho %s' % x field_name = u'field%s' % x field_name2 = u'fieldone%s' % x tag_name = u'tag%s' % x user_name = u'user%s' % x user_pass = u'pass%s' % x user_note = u'note%s' % x user_roles = [u'rolehold', u'role%s' % x] bag = Bag(bag_name) bag.policy.owner = u'owner%s' % x bag.policy.read = [u'hi%s' % x, u'andextra'] bag.policy.manage = [u'R:hi%s' % x, u'andmanage'] store.put(bag) recipe = Recipe(recipe_name) recipe.policy.owner = u'owner%s' % x recipe.policy.read = [u'hi%s' % x, u'andextra'] recipe.policy.manage = [u'R:hi%s' % x, u'andmanage'] recipe.set_recipe(recipe_list) store.put(recipe) tiddler = Tiddler(tiddler_name, bag_name) tiddler.text = tiddler_text tiddler.fields[field_name] = field_name tiddler.fields[field_name2] = field_name2 tiddler.fields['server.host'] = 'gunky' tiddler.tags = [tag_name] store.put(tiddler) store.put(tiddler) user = User(user_name) user.set_password(user_pass) user.note = user_note for role in user_roles: user.add_role(role) store.put(user) bags = [bag.name for bag in store.list_bags()] recipes = [recipe.name for recipe in store.list_recipes()] users = [user.usersign for user in store.list_users()] assert len(bags) == RANGE assert len(recipes) == RANGE assert len(users) == RANGE for x in xrange(RANGE): bname = 'bag%s' % x rname = 'recipe%s' % x uname = 'user%s' % x assert bname in bags assert rname in recipes assert uname in users tiddler = store.get(Tiddler(u'tiddler0', u'bag0')) assert tiddler.fields['field0'] == 'field0' assert tiddler.fields['fieldone0'] == 'fieldone0' bag = Bag(u'bag0') bag = store.get(bag) tiddlers = [] for tiddler in store.list_bag_tiddlers(bag): tiddlers.append(store.get(tiddler)) assert len(tiddlers) == 1 assert tiddlers[0].title == 'tiddler0' assert tiddlers[0].fields['field0'] == 'field0' assert tiddlers[0].fields['fieldone0'] == 'fieldone0' assert tiddlers[0].tags == ['tag0'] assert sorted(bag.policy.read) == ['andextra', 'hi0'] assert sorted(bag.policy.manage) == ['R:hi0', u'andmanage'] assert bag.policy.owner == 'owner0' user = User(u'user1') user = store.get(user) assert user.usersign == 'user1' assert user.check_password('pass1') assert user.note == 'note1' assert 'role1' in user.list_roles() assert 'rolehold' in user.list_roles() recipe = Recipe(u'recipe2') recipe = store.get(recipe) assert recipe.name == 'recipe2' bags = [bag_name for bag_name, filter in recipe.get_recipe()] assert len(bags) == 1 assert 'bag2' in bags assert sorted(recipe.policy.read) == ['andextra', 'hi2'] assert sorted(recipe.policy.manage) == ['R:hi2', u'andmanage'] assert recipe.policy.owner == 'owner2' recipe.policy.manage = [u'andmanage'] store.put(recipe) recipe = Recipe (u'recipe2') recipe = store.get(recipe) assert recipe.policy.manage == [u'andmanage'] # delete the above things store.delete(bag) py.test.raises(NoBagError, 'store.delete(bag)') py.test.raises(NoBagError, 'store.get(bag)') store.delete(recipe) py.test.raises(NoRecipeError, 'store.delete(recipe)') py.test.raises(NoRecipeError, 'store.get(recipe)') store.delete(user) py.test.raises(NoUserError, 'store.delete(user)') py.test.raises(NoUserError, 'store.get(user)') tiddler = Tiddler(u'tiddler9', u'bag9') store.get(tiddler) assert tiddler.bag == 'bag9' assert tiddler.text == 'hey ho 9' assert tiddler.tags == ['tag9'] assert tiddler.fields['field9'] == 'field9' assert 'server.host' not in tiddler.fields store.delete(tiddler) py.test.raises(NoTiddlerError, 'store.delete(tiddler)') py.test.raises(NoTiddlerError, 'store.get(tiddler)')
def test_make_a_bunch(): for x in xrange(RANGE): bag_name = u"bag%s" % x recipe_name = u"recipe%s" % x tiddler_name = u"tiddler%s" % x recipe_list = [(bag_name, "")] tiddler_text = u"hey ho %s" % x field_name = u"field%s" % x tag_name = u"tag%s" % x user_name = u"user%s" % x user_pass = u"pass%s" % x user_note = u"note%s" % x user_roles = [u"rolehold", u"role%s" % x] bag = Bag(bag_name) bag.policy.owner = u"owner%s" % x bag.policy.read = [u"hi%s" % x, u"andextra"] bag.policy.manage = [u"R:hi%s" % x, u"andmanage"] store.put(bag) recipe = Recipe(recipe_name) recipe.policy.owner = u"owner%s" % x recipe.policy.read = [u"hi%s" % x, u"andextra"] recipe.policy.manage = [u"R:hi%s" % x, u"andmanage"] recipe.set_recipe(recipe_list) store.put(recipe) tiddler = Tiddler(tiddler_name, bag_name) tiddler.text = tiddler_text tiddler.fields[field_name] = field_name tiddler.fields["server.host"] = u"gunky" tiddler.tags = [tag_name] store.put(tiddler) user = User(user_name) user.set_password(user_pass) user.note = user_note for role in user_roles: user.add_role(role) store.put(user) bags = [bag.name for bag in store.list_bags()] recipes = [recipe.name for recipe in store.list_recipes()] users = [user.usersign for user in store.list_users()] assert len(bags) == RANGE assert len(recipes) == RANGE assert len(users) == RANGE for x in xrange(RANGE): bname = u"bag%s" % x rname = u"recipe%s" % x uname = u"user%s" % x assert bname in bags assert rname in recipes assert uname in users bag = Bag("bag0") bag = store.get(bag) tiddlers = [] for tiddler in store.list_bag_tiddlers(bag): tiddlers.append(store.get(tiddler)) assert len(tiddlers) == 1 assert tiddlers[0].title == "tiddler0" assert tiddlers[0].fields["field0"] == "field0" assert tiddlers[0].tags == ["tag0"] assert sorted(bag.policy.read) == ["andextra", "hi0"] assert sorted(bag.policy.manage) == ["R:hi0", "andmanage"] assert bag.policy.owner == "owner0" bag = Bag("bag0") bag = store.get(bag) bag.policy.read.remove("hi0") store.put(bag) bag = Bag("bag0") bag = store.get(bag) assert bag.policy.read == [u"andextra"] bag = Bag("bag0") bag = store.get(bag) bag.policy.read.append(u"hi0") store.put(bag) bag = Bag("bag0") bag = store.get(bag) assert sorted(bag.policy.read) == ["andextra", "hi0"] user = User("user1") user = store.get(user) assert user.usersign == "user1" assert user.check_password("pass1") assert user.note == "note1" assert "role1" in user.list_roles() assert "rolehold" in user.list_roles() recipe = Recipe("recipe2") recipe = store.get(recipe) assert recipe.name == "recipe2" bags = [bag_name for bag_name, filter in recipe.get_recipe()] assert len(bags) == 1 assert "bag2" in bags assert sorted(recipe.policy.read) == ["andextra", "hi2"] assert sorted(recipe.policy.manage) == ["R:hi2", "andmanage"] assert recipe.policy.owner == "owner2" recipe.policy.manage = [u"andmanage"] store.put(recipe) recipe = Recipe("recipe2") recipe = store.get(recipe) assert recipe.policy.manage == ["andmanage"] # delete the above things store.delete(bag) py.test.raises(NoBagError, "store.delete(bag)") py.test.raises(NoBagError, "store.get(bag)") store.delete(recipe) py.test.raises(NoRecipeError, "store.delete(recipe)") py.test.raises(NoRecipeError, "store.get(recipe)") store.delete(user) py.test.raises(NoUserError, "store.delete(user)") py.test.raises(NoUserError, "store.get(user)") tiddler = Tiddler("tiddler9", "bag9") store.get(tiddler) assert tiddler.bag == "bag9" assert tiddler.text == "hey ho 9" assert tiddler.tags == ["tag9"] assert tiddler.fields["field9"] == "field9" assert "server.host" not in tiddler.fields store.delete(tiddler) py.test.raises(NoTiddlerError, "store.delete(tiddler)") py.test.raises(NoTiddlerError, "store.get(tiddler)")
def register(environ, start_response): """ register the user """ config = environ['tiddlyweb.config'] store = environ['tiddlyweb.store'] query = environ['tiddlyweb.query'] try: server_name = query['server_name'][0] server_name_sig = query['server_name_sig'][0] server_login = query['server_login'][0] server_login_sig = query['server_login_sig'][0] username = query['login'][0] name = query['name'][0] email = query['email'][0] extra = query['extra'][0] redirect = query['redirect'][0] except (KeyError, ValueError) as exc: raise HTTP400('Incomplete form submission: %s' % exc) announcements = query.get('announcements', [None])[0] # Bail out if someone corrupted the form input. secret = config['secret'] name_sig = sha('%s%s' % (server_name, secret)).hexdigest() login_sig = sha('%s%s' % (server_login, secret)).hexdigest() if name_sig != server_name_sig or login_sig != server_login_sig: raise HTTP400('Invalid request') user = User(username) try: store.get(user) raise HTTP400('That username is not available.') except StoreError: # we expect and want this pass user.add_role(DEFAULT_ROLE) user.note = simplejson.dumps({ 'registered': time(), 'name': name, 'email': email, 'extra': extra, 'announcements': announcements is not None }) map_bag_name = config.get('magicuser.map', 'MAPUSER') ensure_bag(map_bag_name, store, policy_dict=MAP_USER_POLICY) tiddler = Tiddler(server_login, map_bag_name) try: store.get(tiddler) raise HTTP400('That remote user is already mapped') except StoreError: pass tiddler.fields['mapped_user'] = username store.put(tiddler) store.put(user) create_wiki(environ, '_%s-data' % username, mode='private', username=username, desc='Data Files', validate=False) create_wiki(environ, '%s-notebook' % username, mode='private', username=username, desc='Private Notebook', validate=False) create_wiki(environ, '%s' % username, mode='protected', username=username, desc='Share Stuff', validate=False) redirect_uri = '%s%s' % (server_base_url(environ), redirect) secret = config['secret'] cookie_age = config.get('cookie_age', None) cookie_header_string = make_cookie('tiddlyweb_user', server_login, mac_key=secret, path='/', expires=cookie_age) start_response('303 See Other', [('Set-Cookie', cookie_header_string), ('Content-Type', 'text/plain'), ('Location', str(redirect_uri))]) return [redirect_uri]