def _create_user(request, username=None): """ helper to create users ie POST /user or PUT /user/<username> """ if not request.context.user.has_perm(PERM_CREATE, User): return HttpResponse(status=401) try: params = _get_params_by_ct(request) if username is None: username = params.get('username') # validate if not VALID_USERNAME.match(username): return HttpResponse('Invalid username', status=400, content_type="text/plain") if 'password' in params: if (not 'password2' in params or params['password2'] != params['password']): return HttpResponse('Passwords did not match', status=400, content_type="text/plain") except: return HttpResponse('Error parsing parameters', status=400, content_type="text/plain") try: user = User(username=username) if 'password' in params: user.set_password(params['password']) user.store(request.context.get_users_database()) return HttpResponse(status=201) except ResourceConflict: return HttpResponse(status=409)
def setUp(self): # XXX load it! self.config = {'web.apps': ['radarpost.web.api'], 'web.debug': True, 'web.static_files_url': '/static', 'beaker.session.type': 'memory', 'couchdb.users_database': self.TEST_USERS_DB, 'couchdb.address': 'http://localhost:5984', 'couchdb.prefix': 'radar/' } self.url_gen = URLGenerator(build_routes(self.config), {}) # set-up users database couchdb = get_couchdb_server(self.config) dbname = self.config['couchdb.users_database'] if dbname in couchdb: del couchdb[dbname] self._users_db = couchdb.create(dbname) # create an admin admin = User(username=self.TEST_ADMIN_USER, password=self.TEST_ADMIN_PASSWORD) admin.roles = [ROLE_ADMIN] admin.store(self._users_db)
def test_user_exists(self): uname = 'joe' udb = self.get_users_database() user_url = self.url_for('user_rest', userid=uname) c = self.get_test_app() c.head(user_url, status=404) user = User(username=uname) user.store(udb) c.head(user_url, status=200)
def test_delete_user(self): uname = 'joe' udb = self.get_users_database() user_url = self.url_for('user_rest', userid=uname) user = User(username=uname) user.store(udb) c = self.get_test_app() self.login_as_admin(c) c.head(user_url, status=200) c.delete(user_url, status=200) c.head(user_url, status=404) c.delete(user_url, status=404)
def test_user_id_requirement(): user = User(username='******', password='******') assert user.username == 'joe' assert user.id == "org.couchdb.user:joe" db = create_test_users_db() user.store(db) user = User.load(db, "org.couchdb.user:joe") assert user.username == 'joe' user = User.get_by_username(db, "joe") assert user.username == 'joe' assert user.id == "org.couchdb.user:joe"
def setUp(self): self.config = load_test_config() self.url_gen = URLGenerator(build_routes(self.config), {}) # set-up users database couchdb = get_couchdb_server(self.config) dbname = self.config['couchdb.users_database'] if dbname in couchdb: del couchdb[dbname] self._users_db = couchdb.create(dbname) # create an admin admin = User(username=self.config['test.admin_user'], password=self.config['test.admin_password']) admin.roles = [ROLE_ADMIN] admin.store(self._users_db)
def _update_user(request, username): """ updates user info ie POST /user/<username> """ udb = request.context.get_users_database() user = User.get_by_username(udb, username) if user is None: return HttpResponse(status=404) if not request.context.user.has_perm(PERM_UPDATE, obj=user): return HttpResponse(status=401) try: params = _get_params_by_ct(request) if 'password' in params: if (not 'password2' in params or params['password2'] != params['password']): return HttpResponse('Passwords did not match', status=400, content_type="text/plain") user.set_password(params['password']) except: return HttpResponse(status=400) try: user.store(udb) return HttpResponse(status=200) except ResourceConflict: return HttpResponse(status=409)
def login(request): """ handles session login """ try: params = _get_params_by_ct(request) username = params['username'] password = params['password'] except: return HttpResponse(status=400) # attempt actual login... udb = request.context.get_users_database() user = User.get_by_username(udb, username) if user is None: return HttpResponse(status=401) if not user.check_password(password): return HttpResponse(status=401) # password was good, record in session request.context.set_session_user(user) if 'next' in params: req = HttpResponse(status=304) req.location = params['next'] return req else: return HttpResponse()
def __call__(self, username, is_locked=False): """ Reset the password of the user with the given username. is_locked - if True, lock the user's password """ couchdb = Server(self.config['couchdb.address']) try: udb = couchdb[self.config['couchdb.users_database']] except: print "Failed to connect to couchdb at %s/%s" % (self.config['couchdb.address'], self.config['couchdb.users_database']) return 1 try: user = User.get_by_username(udb, username) except ResourceNotFound: print 'User "%s" does not exist' % username return 1 if not is_locked: done = False while(not done): password = getpass(prompt="New password for %s: " % username) password2 = getpass(prompt="Repeat password: "******"Passwords did not match, try again.\n" user.set_password(password) else: user.lock_password() user.store(udb) print 'Password changed for user "%s"' % username
def test_login_json(self): uname = 'joe' password = '******' badpw = 'lb0w' udb = self.get_users_database() user = User(username=uname, password=password) user.store(udb) login_url = self.url_for('login') logout_url = self.url_for('logout') c = self.get_test_app() # not logged in res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == True assert info.get('userid', None) is None # bad login c.post(login_url, json.dumps({'username': uname, 'password': badpw}), content_type="application/json", status=401) res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == True assert info.get('userid', None) is None # successfull login c.post(login_url, json.dumps({'username': uname, 'password': password}), content_type="application/json", status=200) res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == False assert info['userid'] == 'joe' # logout c.post(logout_url, status=200) res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == True assert info.get('userid', None) is None
def _user_exists(request, username): """ tests existance of user with the given username ie HEAD /user/<username> """ udb = request.context.get_users_database() user = User.get_by_username(udb, username) if user is None or not user.type == 'user': return HttpResponse(status=404) else: return HttpResponse(status=200)
def __call__(self, username, is_locked=False, is_admin=False): """ Create a user with the given username. is_locked - if True, create with a locked password is_admin - if True, grant administrative rights to the user """ couchdb = Server(self.config['couchdb.address']) try: udb = couchdb[self.config['couchdb.users_database']] except: print "Failed to connect to couchdb at %s/%s" % (self.config['couchdb.address'], self.config['couchdb.users_database']) return 1 new_user = User(username=username) if new_user.id in udb: print 'User "%s" already exists' % username return 1 if not is_locked: done = False while(not done): password = getpass(prompt="Password for %s: " % username) password2 = getpass(prompt="Repeat password: "******"Passwords did not match, try again.\n" new_user.set_password(password) if is_admin: new_user.roles = [ROLE_ADMIN] new_user.store(udb) print 'Created user "%s"' % username
def _delete_user(request, username): """ deletes a user """ udb = request.context.get_users_database() user = User.get_by_username(udb, username) if user is None or not user.type == 'user' or not user.username == username: return HttpResponse(status=404) if not request.context.user.has_perm(PERM_DELETE, user): return HttpResponse(status=401) del udb[user.id] return HttpResponse(status=200)
def check_http_auth(request): if request.authorization: ctx = request.context try: meth, params = request.authorization if meth.lower() == 'basic': username, password = base64.b64decode(params).split(':') udb = ctx.get_users_database() user = User.get_by_username(udb, username) if user is not None and user.check_password(password) == True: ctx.set_request_user(user) return except: pass raise BadAuthenticator()
def test_login_basic_auth(self): uname = 'joe' password = '******' badpw = 'lb0w' udb = self.get_users_database() user = User(username=uname, password=password) user.store(udb) c = self.get_test_app() # not logged in # res = c.get(self.url_for('current_user_info')) # info = json.loads(res.body) # assert info['is_anonymous'] == True # assert info.get('userid', None) is None bad_method = ('Authorization', 'Bad Bad=News') c.get(self.url_for('current_user_info'), headers=[bad_method], status=401) bad_auth = _basic_auth(uname, badpw) c.get(self.url_for('current_user_info'), headers=[bad_auth], status=401) # should be joe for this request good_auth = _basic_auth(uname, password) res = c.get(self.url_for('current_user_info'), headers=[good_auth]) info = json.loads(res.body) assert info['is_anonymous'] == False assert info['userid'] == 'joe' # but this is not persistent res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == True assert info.get('userid', None) is None
def test_user_password(): user = User(username='******', password='******') assert user.username == 'joe' assert user.check_password('fr3d') assert not user.check_password('fr01d') db = create_test_users_db() user.store(db) user = User.load(db, user.id) assert user.check_password('fr3d') assert not user.check_password('fr01d') assert user.username == 'joe'
def test_create_user_json_put(self): """ tests creating a user by PUT'ing json-encoded parameters to /user/<username> """ uname = 'joe' uid = 'org.couchdb.user:%s' % uname udb = self.get_users_database() create_url = self.url_for('user_rest', userid=uname) assert not uid in udb c = self.get_test_app() self.login_as_admin(c) c.put(create_url, json.dumps({}), content_type="application/json", status=201) assert uid in udb c.put(create_url, json.dumps({}), content_type="application/json", status=409) del udb[uid] # test passwords. password = '******' bad_pass = '******' # missing password 2 c.put(create_url, json.dumps({'password': password}), content_type="application/json", status=400) assert uid not in udb # passwords don't match c.put(create_url, json.dumps({'password': password, 'password2': bad_pass}), content_type="application/json", status=400) assert uid not in udb # okay c.put(create_url, json.dumps({'password': password, 'password2': password}), content_type="application/json", status=201) user = User.get_by_username(udb, uname) assert user.check_password(password) assert not user.check_password(bad_pass)
def user(self): """ Property that returns the currently logged in user """ if self._current_user is None and self.USER_SESSION_KEY in self.session: try: user_id = self.session[self.USER_SESSION_KEY] udb = self.get_users_database() self._current_user = User.load(udb, user_id) except ResourceNotFound: # non-existant user, wipe this session self.session.invalidate() if self._current_user is None: self._current_user = AnonymousUser() return self._current_user
def _user_info(request, user): """ helper that handles retreiving user info ie GET /user/<userid> or GET /user """ if isinstance(user, basestring): udb = request.context.get_users_database() user = User.get_by_username(udb, user) if user is None: return HttpResponse(status=404) if user.is_anonymous(): info = {'is_anonymous': True} else: info = {'is_anonymous': False, 'userid': user.username, 'name': user.get_public_id()} return HttpResponse(json.dumps(info), content_type="application/json")
def test_create_user_urlenc_post(self): """ tests creating a user by POST'ing form-encoded parameters to /user """ uname = 'joe' uid = 'org.couchdb.user:%s' % uname udb = self.get_users_database() create_url = self.url_for('create_user') assert not uid in udb c = self.get_test_app() self.login_as_admin(c) c.post(create_url, {'username': uname}, status=201) assert uid in udb c.post(create_url, {'username': uname}, status=409) del udb[uid] # test passwords. password = '******' bad_pass = '******' # missing password 2 c.post(create_url, {'username': uname, 'password': password}, status=400) assert uid not in udb # passwords don't match c.post(create_url, {'username': uname, 'password': password, 'password2': bad_pass}, status=400) assert uid not in udb # okay c.post(create_url, {'username': uname, 'password': password, 'password2': password}, status=201) user = User.get_by_username(udb, uname) assert user.check_password(password) assert not user.check_password(bad_pass)
def test_basic_auth_overrides_cookie(self): uname = 'joe' password = '******' badpw = 'lb0w' uname2 = 'jane' password2 = 'j03' udb = self.get_users_database() user = User(username=uname, password=password) user.store(udb) user2 = User(username=uname2, password=password2) user2.store(udb) c = self.get_test_app() # not logged in res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == True assert info.get('userid', None) is None # successfull login login_url = self.url_for('login') c.post(login_url, {'username': user.username, 'password': password}, status=200) res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == False assert info['userid'] == user.username # do a request with basic auth for the other user... res = c.get(self.url_for('current_user_info'), headers=[_basic_auth(user2.username, password2)]) info = json.loads(res.body) assert info['is_anonymous'] == False assert info['userid'] == user2.username # this should not affect the session. res = c.get(self.url_for('current_user_info')) info = json.loads(res.body) assert info['is_anonymous'] == False assert info['userid'] == user.username
def test_update_user_passwd_post_urlenc(self): uname = 'joe' pw1 = 'bl0w' pw2 = 'b0w1' udb = self.get_users_database() user_url = self.url_for('user_rest', userid=uname) c = self.get_test_app() self.login_as_admin(c) c.post(user_url, {}, status=404) user = User(username=uname, password=pw1) user.store(udb) user = User.get_by_username(udb, uname) assert user.check_password(pw1) assert not user.check_password(pw2) # missing password2 c.post(user_url, {'username': uname, 'password': pw2}, status=400) user = User.get_by_username(udb, uname) assert user.check_password(pw1) assert not user.check_password(pw2) # passwords don't match c.post(user_url, {'username': uname, 'password': pw2, 'password2': pw1}, status=400) user = User.get_by_username(udb, uname) assert user.check_password(pw1) assert not user.check_password(pw2) # okay c.post(user_url, {'username': uname, 'password': pw2, 'password2': pw2}, status=200) user = User.get_by_username(udb, uname) assert user.check_password(pw2) assert not user.check_password(pw1)