def check_access(self, name, handle): """Check to see what level of access user has over an owner's project. Returns one of: Access.Denied, Access.ReadOnly or Access.ReadWrite Note that if user==owner then no check of project_name is performed, and Access.ReadWrite is returned straight away""" try: (user_name, project_name, path) = name.split("/", 2) requester = get_username_from_handle(handle) user = User.find_user(requester) owner = User.find_user(user_name) if user == owner: return Access.ReadWrite if user != owner: if owner.is_project_shared(project_name, user, require_write=True): return Access.ReadWrite if owner.is_project_shared(project_name, user, require_write=False): return Access.ReadOnly else: return Access.Denied except: log.exception("Error in Persister.check_access() for name=%s, handle=%s", name, handle) return Access.Denied
def test_delete_setting(): resp = app.post('/settings/', {'newone' : 'hi there'}) resp = app.delete('/settings/newone') user = User.find_user('BillBixby') session.expunge(user) user = User.find_user('BillBixby') assert 'newone' not in user.settings
def check_access(self, name): from bespin.database import User, get_project (user_name, project_name, path) = name.split("/", 2) user = User.find_user(user_name) parts = project_name.partition('+') if parts[1] == '': owner = user else: owner = User.find_user(parts[0]) project_name = parts[2] project = get_project(user, owner, project_name) return (project, path)
def _split_path(self, path, handle): """Extract user, owner, project name, and path and return it as a tuple.""" requester = get_username_from_handle(handle) user = User.find_user(requester) if path[0] == "/": path = path[1:] result = path.split('/', 1) parts = result[0].partition('+') if parts[1] == '': result.insert(0, user) else: result.insert(0, User.find_user(parts[0])) result[1] = parts[2] result.insert(0, user) return result
def _split(self, name): """Cut a name into the username, projectname, path parts and lookup a project under the given user""" (user_name, project_name, path) = name.split("/", 2) user = User.find_user(user_name) project = get_project(user, user, project_name) return (project, path)
def vcs_error(qi, e): """Handles exceptions that come up during VCS operations. A message is added to the user's message queue.""" log.debug("Handling VCS error: %s", e) s = database._get_session() user = qi.message['user'] # if the user hadn't already been looked up, go ahead and pull # them out of the database if isinstance(user, basestring): user = User.find_user(user) else: s.add(user) # if we didn't find the user in the database, there's not much # we can do. if user: if isinstance(e, (FSException, main.UVCError)): # for exceptions that are our types, just display the # error message tb = str(e) else: # otherwise, it looks like a programming error and we # want more information tb = format_exc() message = dict(jobid=qi.id, output=tb, error=True) message['asyncDone'] = True retval = Message(user_id=user.id, message=simplejson.dumps(message)) s.add(retval)
def test_register_and_verify_user(): config.activate_profile() _clear_db() s = _get_session() app = controllers.make_app() app = BespinTestApp(app) resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******")) assert resp.content_type == "application/json" data = simplejson.loads(resp.body) assert data == {} assert resp.cookies_set['auth_tkt'] assert app.cookies billbixby = User.find_user("BillBixby") sample_project = get_project(billbixby, billbixby, "SampleProject") files = [file.name for file in sample_project.list_files()] assert "readme.txt" in files # should be able to run again without an exception appearing resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******"), status=409) # with the cookie set, we should be able to retrieve the # logged in name resp = app.get('/register/userinfo/') assert resp.content_type == 'application/json' data = simplejson.loads(resp.body) assert data['username'] == 'BillBixby' assert 'quota' in data assert data['quota'] == 15728640 assert 'amountUsed' in data resp = app.get("/file/at/BespinSettings/config") app.post("/file/close/BespinSettings/config")
def _init_data(): global macgyver, someone_else, murdoc config.activate_profile() fsroot = config.c.fsroot if fsroot.exists() and fsroot.basename() == "testfiles": fsroot.rmtree() fsroot.makedirs() app.reset() Base.metadata.drop_all(bind=config.c.dbengine) Base.metadata.create_all(bind=config.c.dbengine) s = config.c.session_factory() someone_else = User.create_user("SomeoneElse", "", "*****@*****.**") murdoc = User.create_user("Murdoc", "", "*****@*****.**") otherproject = get_project(someone_else, someone_else, "otherproject", create=True) otherproject.save_file('foo', 'Just a file to reserve a project') app.post("/register/new/MacGyver", dict(password="******", email="*****@*****.**")) macgyver = User.find_user("MacGyver")
def user(self): if self._user: return self._user if self.username: self._user = User.find_user(self.username) return self._user return None
def lost(request, response): """Generates lost password email messages""" email = request.POST.get('email') username = request.POST.get('username') if username: user = User.find_user(username) if not user: raise BadRequest("Unknown user: "******"?pwchange=%s;%s" % (username, verify_code) context = dict(username=username, base_url=c.base_url, change_url=change_url) send_email_template(user.email, "Requested password change for " + c.base_url, "lost_password.txt", context) elif email: users = User.find_by_email(email) context = dict(email=email, usernames=[dict(username=user.username) for user in users], base_url=c.base_url) send_email_template(email, "Your username for " + c.base_url, "lost_username.txt", context) else: raise BadRequest("Username or email is required.") return response()
def lost(request, response): """Generates lost password email messages""" email = request.POST.get('email') username = request.POST.get('username') if username: user = User.find_user(username) if not user: raise BadRequest("Unknown user: "******"?pwchange=%s;%s" % (username, verify_code) context = dict(username=username, base_url=c.base_url, change_url=change_url) send_email_template(user.email, "Requested password change for " + c.base_url, "lost_password.txt", context) elif email: users = User.find_by_email(email) context = dict( email=email, usernames=[dict(username=user.username) for user in users], base_url=c.base_url) send_email_template(email, "Your username for " + c.base_url, "lost_username.txt", context) else: raise BadRequest("Username or email is required.") return response()
def test_set_settings(): resp = app.post('/settings/', {'antigravity' : 'on', 'write_my_code' : 'on'}) assert not resp.body user = User.find_user('BillBixby') session.expunge(user) user = User.find_user('BillBixby') assert user.settings['antigravity'] == 'on' assert user.settings['write_my_code'] == 'on' resp = app.get('/settings/') assert resp.content_type == 'application/json' data = simplejson.loads(resp.body) assert data == {'antigravity' : 'on', 'write_my_code' : 'on'} resp = app.get('/settings/antigravity') assert resp.content_type == "application/json" assert resp.body == '"on"'
def test_setup(request, response): for name in test_users: user = User.find_user(name) if (user == None): user = User.create_user(name, name, name) response.body = "" response.content_type = "text/plain" return response()
def test_password_change_with_confirmation_code(): config.set_profile("test") config.activate_profile() _clear_db() app = controllers.make_app() app = BespinTestApp(app) resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******")) app.reset() user = User.find_user("BillBixby") verify_code = controllers._get_password_verify_code(user) resp = app.post('/register/password/BillBixby', dict(code=verify_code, newPassword="******")) user = User.find_user('BillBixby', 'hatetraffic') assert user
def test_password_change_with_confirmation_code(): config.set_profile("test") config.activate_profile() _clear_db() app = controllers.make_app() app = BespinTestApp(app) resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******")) app.reset() user = User.find_user("BillBixby") verify_code = controllers._get_password_verify_code(user) resp = app.post('/register/password/BillBixby', dict( code=verify_code, newPassword="******")) user = User.find_user('BillBixby', 'hatetraffic') assert user
def clone_run(qi): """Runs the queued up clone job.""" message = qi.message s = database._get_session() user = User.find_user(message['user']) message['user'] = user result = _clone_impl(**message) result.update(dict(jobid=qi.id, asyncDone=True)) retvalue = Message(user_id=user.id, message=simplejson.dumps(result)) s.add(retvalue) config.c.stats.incr('vcs_DATE')
def _split_path(request): path = request.kwargs['path'] result = path.split('/', 1) if len(result) < 2: raise BadRequest("Project and path are both required.") parts = result[0].partition('+') if parts[1] == '': result.insert(0, request.user) else: result.insert(0, User.find_user(parts[0])) result[1] = parts[2] return result
def password_change(request, response): """Changes a user's password.""" username = request.kwargs.get('username') user = User.find_user(username) if not user: raise BadRequest("Unknown user: "******"Invalid verification code for password change.") user.password = User.generate_password(request.POST['newPassword']) return response()
def test_create_duplicate_user(): s = _get_session(True) u = User.create_user("BillBixby", "somepass", "*****@*****.**") s.commit() original_password = u.password try: User.create_user("BillBixby", "otherpass", "*****@*****.**") assert False, "Should have gotten a ConflictError" except ConflictError: s.rollback() s = _get_session(False) user = User.find_user("BillBixby") assert user.password == original_password, "Password should not have changed"
def test_register_existing_user_should_not_authenticate(): s = _get_session(True) app_orig = controllers.make_app() app = BespinTestApp(app_orig) resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******")) app = BespinTestApp(app_orig) resp = app.post("/register/new/BillBixby", dict(email="*****@*****.**", password="******"), status=409) assert not resp.cookies_set user = User.find_user("BillBixby", 'notangry') assert user is not None
def get_user(name): user = User.find_user(name) if user == None: user = User.create_user(name, name, name + "@foo.com") session.commit() info("Created user called '" + name + "'") try: filesystem.get_project(user, user, "BespinSettings") except: settings = filesystem.get_project(user, user, "BespinSettings", create=True) settings.install_template('usertemplate') info("Created BespinSettings project for '" + name + "'") return user
def clone_run(qi): """Runs the queued up clone job.""" message = qi.message s = database._get_session() user = User.find_user(message['user']) message['user'] = user # wrap the output in "output" in a new dictionary, because # the client will peel off one layer from this. result = dict(output=_clone_impl(qid=qi.id, **message)) result.update(dict(jobid=qi.id, asyncDone=True)) retvalue = Message(user_id=user.id, message=simplejson.dumps(result)) s.add(retvalue) config.c.stats.incr('vcs_DATE')
def test_get_users_settings(): _clear_db() app = controllers.make_app() app = BespinTestApp(app) resp = app.post("/register/new/macgyver", dict(password="******", email="*****@*****.**")) resp = app.put("/file/at/BespinSettings/settings", """ vcsuser Mack Gyver <*****@*****.**> """) s = _get_session() macgyver = User.find_user("macgyver") settings = macgyver.get_settings() assert settings == dict(vcsuser="******")
def deploy_impl(qi): """Executed via the worker queue to actually deploy the project.""" message = qi.message kcpass = message['kcpass'] options = _OptionHolder(message['options']) s = _get_session() user = User.find_user(message['user']) project = get_project(user, user, message['project']) pdo = ProjectDeploymentOptions.get(project) keychain = DeploymentKeyChain(user, kcpass) credentials = keychain.get_credentials_for_project(project) cwd = os.getcwd() keyfile = None options.username = credentials['username'] if credentials['type'] == 'ssh': keyfile = TempSSHKeyFile() keyfile.store(credentials['ssh_public_key'], credentials['ssh_private_key']) options.sshkey = keyfile.filename else: options.password = credentials['password'] desturl = "sftp://%s/%s" % (quote(pdo.remote_host, safe=""), quote(pdo.remote_directory)) try: os.chdir(project.location) log.debug("Computed destination URL: %s", desturl) log.debug("Running with options: %r", options) error, output = _launch_sync(qi.id, user.id, desturl, options) # there's an extra layer around the output that is # expected by the client result = dict(output=dict(output=output, error=error)) result.update(dict(jobid=qi.id, asyncDone=True)) retvalue = Message(user_id=user.id, message=dumps(result)) s.add(retvalue) finally: if keyfile: keyfile.delete() os.chdir(cwd)
def run_command_run(qi): """Runs the queued up run_command job.""" message = qi.message s = database._get_session() user = User.find_user(message['user']) message['user'] = user message['project'] = get_project(user, user, message['project']) result = _run_command_impl(**message) result.update(dict(eventName="vcs:response", asyncDone=True)) retvalue = Message(user_id=user.id, message=simplejson.dumps(result)) s.add(retvalue) config.c.stats.incr('vcs_DATE')
def test_create_new_user(): s = _get_session(True) num_users = s.query(User).count() assert num_users == 0 user = User.create_user("BillBixby", "hulkrulez", "*****@*****.**") assert len(user.uuid) == 36 num_users = s.query(User).count() assert num_users == 1 result = s.connection().execute(EventLog.select()).fetchall() assert len(result) == 1 users = User.find_by_email("*****@*****.**") assert users[0].username == "BillBixby" assert len(users) == 1 user = User.find_user("*****@*****.**") assert user == users[0]
def test_lost_password_request(send_text_email): config.set_profile("test") config.activate_profile() _clear_db() app = controllers.make_app() app = BespinTestApp(app) resp = app.post('/register/new/BillBixby', dict(email="*****@*****.**", password="******")) app.reset() resp = app.post('/register/lost/', dict(username='******')) assert send_text_email.called args = send_text_email.call_args[0] assert args[0] == '*****@*****.**' assert args[1].startswith("Requested password change for ") user = User.find_user("BillBixby") verify_code = controllers._get_password_verify_code(user) assert verify_code in args[2]
def _init_data(): global macgyver config.activate_profile() fsroot = config.c.fsroot if fsroot.exists() and fsroot.basename() == "testfiles": fsroot.rmtree() fsroot.makedirs() app.reset() Base.metadata.drop_all(bind=config.c.dbengine) Base.metadata.create_all(bind=config.c.dbengine) s = config.c.session_factory() app.post("/register/new/MacGyver", dict(password="******", email="*****@*****.**")) macgyver = User.find_user("MacGyver") s.flush()
def test_messages_sent_from_server_to_user(): _clear_db() app = controllers.make_app() app = BespinTestApp(app) resp = app.post("/register/new/macgyver", dict(password="******", email="*****@*****.**")) s = _get_session() macgyver = User.find_user("macgyver") assert len(macgyver.messages) == 0 macgyver.publish(dict(my="message")) s.commit() resp = app.post("/messages/") assert resp.content_type == "application/json" data = simplejson.loads(resp.body) assert len(data) == 1 assert data[0] == dict(my="message") # the message should be consumed resp = app.post("/messages/") data = simplejson.loads(resp.body) assert len(data) == 0
def test_hg_clone_on_web(run_command_params): _init_data() resp = app.post("/vcs/clone/", dict(source="http://hg.mozilla.org/labs/bespin", dest="bigmac", push="ssh://hg.mozilla.org/labs/bespin", remoteauth="both", authtype="password", username="******", password="******", kcpass="******" )) assert resp.content_type == "application/json" output = simplejson.loads(resp.body) assert 'jobid' in output resp = app.post("/messages/") messages = simplejson.loads(resp.body) assert len(messages) == 1 output = messages[0] assert output['project'] == "bigmac" assert 'output' in output output = output['output'] command, context = run_command_params working_dir = context.working_dir global macgyver macgyver = User.find_user("MacGyver") command_line = " ".join(command.get_command_line()) assert command_line == "hg clone http://someuser:[email protected]/labs/bespin bigmac" assert working_dir == macgyver.get_location() assert output == clone_output bigmac = get_project(macgyver, macgyver, "bigmac") metadata = bigmac.metadata assert metadata['remote_auth'] == vcs.AUTH_BOTH assert metadata['push'] == "ssh://hg.mozilla.org/labs/bespin" metadata.close()
def test_hg_clone_on_web(run_command_params): _init_data() resp = app.post("/vcs/clone/", dict(source="http://hg.mozilla.org/labs/bespin", dest="bigmac", push="ssh://hg.mozilla.org/labs/bespin", remoteauth="both", authtype="password", username="******", password="******", kcpass="******" )) assert resp.content_type == "application/json" output = simplejson.loads(resp.body) assert 'jobid' in output resp = app.post("/messages/") messages = simplejson.loads(resp.body) assert len(messages) == 2 output = messages[1]['output'] assert output['project'] == "bigmac" assert 'output' in output output = output['output'] command, context = run_command_params working_dir = context.working_dir global macgyver macgyver = User.find_user("MacGyver") command_line = " ".join(command.get_command_line()) assert command_line == "hg clone http://someuser:[email protected]/labs/bespin bigmac" assert working_dir == macgyver.get_location() assert output == clone_output bigmac = get_project(macgyver, macgyver, "bigmac") metadata = bigmac.metadata assert metadata['remote_auth'] == vcs.AUTH_BOTH assert metadata['push'] == "ssh://hg.mozilla.org/labs/bespin" metadata.close()
def login(request, response): username = request.kwargs['login_username'] password = request.POST.get('password') fli = c.login_tracker.can_log_in(username) if not fli.can_log_in: response.status = "401 Not Authorized" response.body = "Locked out due to failed login attempts." return response() user = User.find_user(username, password) if not user: c.login_tracker.login_failed(fli) response.status = "401 Not Authorized" response.body = "Invalid login" return response() c.login_tracker.login_successful(fli) request.environ['paste.auth_tkt.set_user'](username) response.content_type = "application/json" response.body="{}" return response()
def login(request, response): username = request.kwargs['login_username'] password = request.POST.get('password') fli = c.login_tracker.can_log_in(username) if not fli.can_log_in: response.status = "401 Not Authorized" response.body = "Locked out due to failed login attempts." return response() user = User.find_user(username, password) if not user: c.login_tracker.login_failed(fli) response.status = "401 Not Authorized" response.body = "Invalid login" return response() c.login_tracker.login_successful(fli) request.environ['paste.auth_tkt.set_user'](username) response.content_type = "application/json" response.body = "{}" return response()
def test_hg_clone_on_web_with_ssh(run_command_params): _init_data() resp = app.post("/vcs/clone/", dict(source="http://hg.mozilla.org/labs/bespin", push="ssh://hg.mozilla.org/labs/bespin", remoteauth="both", authtype="ssh", kcpass="******" )) assert resp.content_type == "application/json" output = simplejson.loads(resp.body) assert 'jobid' in output resp = app.post("/messages/") messages = simplejson.loads(resp.body) assert len(messages) == 2 output = messages[1] assert 'output' in output output = output['output'] command, context = run_command_params working_dir = context.working_dir global macgyver macgyver = User.find_user("MacGyver") command_line = command.get_command_line() assert command_line[0:3] == ["hg", "clone", "--ssh"] assert command_line[3].startswith("ssh -i") assert command_line[4] == "http://hg.mozilla.org/labs/bespin" assert command_line[5] == "bespin" assert working_dir == macgyver.get_location() assert output['output'] == clone_output bespin = get_project(macgyver, macgyver, "bespin") metadata = bespin.metadata assert metadata['remote_auth'] == vcs.AUTH_BOTH assert metadata['push'] == "ssh://hg.mozilla.org/labs/bespin" metadata.close()
def test_hg_clone_on_web_with_ssh(run_command_params): _init_data() resp = app.post("/vcs/clone/", dict(source="http://hg.mozilla.org/labs/bespin", push="ssh://hg.mozilla.org/labs/bespin", remoteauth="both", authtype="ssh", kcpass="******" )) assert resp.content_type == "application/json" output = simplejson.loads(resp.body) assert 'jobid' in output resp = app.post("/messages/") messages = simplejson.loads(resp.body) assert len(messages) == 1 output = messages[0] assert 'output' in output output = output['output'] command, context = run_command_params working_dir = context.working_dir global macgyver macgyver = User.find_user("MacGyver") command_line = command.get_command_line() assert command_line[0:3] == ["hg", "clone", "-e"] assert command_line[3].startswith("ssh -i") assert command_line[4] == "http://hg.mozilla.org/labs/bespin" assert command_line[5] == "bespin" assert working_dir == macgyver.get_location() assert output == clone_output bespin = get_project(macgyver, macgyver, "bespin") metadata = bespin.metadata assert metadata['remote_auth'] == vcs.AUTH_BOTH assert metadata['push'] == "ssh://hg.mozilla.org/labs/bespin" metadata.close()
def deploy_error(qi, e): """Handles errors that come up during deployment.""" log.debug("Handling deploy error: %s", e) s = _get_session() user = qi.message['user'] # if the user hadn't already been looked up, go ahead and pull # them out of the database if isinstance(user, basestring): user = User.find_user(user) else: s.add(user) # if we didn't find the user in the database, there's not much # we can do. if user: # it looks like a programming error and we # want more information tb = format_exc() print "E:", tb message = dict(jobid=qi.id, output=dict(output=tb, error=True)) message['asyncDone'] = True retval = Message(user_id=user.id, message=dumps(message)) s.add(retval)
def test_get_user_returns_none_for_nonexistent(): s = _get_session(True) user = User.find_user("NOT THERE. NO REALLY!") assert user is None
def lookup_username(username): user = User.find_user(username) if user == None: raise BadRequest("Username not found: %s" % username) return user