def test_clone_other_private_repo_with_access(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) repositories=database.getStore().find(database.Repository) self.assertGreater(repositories.count(), 0) for u in users: self.assertGreater(u.keys.count(), 0) self.assertGreater(u.repositories.count(), 0) key=None for _key in u.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] for r in repositories: if r.getAccess(u)==r.ACC_OWNER: continue r.public=False r.setAccess(u, r.ACC_VIEW) database.getStore().commit() clonedir="%s_%d"%(self.repo_clone_dir, r.repository_id) self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n"%(r.name, r.description)) shutil.rmtree(clonedir)
def test_push_other_private_repo(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) repositories=database.getStore().find(database.Repository) self.assertGreater(repositories.count(), 0) for u in users: self.assertGreater(u.keys.count(), 0) self.assertGreater(u.repositories.count(), 0) key=None for _key in u.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] for r in repositories: if r.getAccess(u)==r.ACC_OWNER: continue r.public=False database.getStore().commit() clonedir="%s_%d"%(self.repo_clone_dir, r.repository_id) #clone the repo self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 128 )
def setUp(self): super(TestUserModel, self).setUp() u=database.User(username=u"user1", email=u"*****@*****.**") u.setPassword(u"password") database.getStore().add(u) database.getStore().commit()
def test_create_repo(self): repo=database.Repository(name=u"test-repo", description=u"Testing Repo") self.repouser.repositories.add(repo) repo.setPath() database.getStore().commit() repo.create() self.assertTrue(os.path.exists(repo.getRepositoryDir())) self.assertEqual(repo.path, unicode(u"/".join((repo.getOwnerName(), repo.name))))
def setUp(self): super(TestRepositoryModel, self).setUp() self.repobase=tempfile.mkdtemp() self.repoclonedir=tempfile.mkdtemp() gitastic.config.configuration=gitastic.config._merged(gitastic.config.configuration, {"Repository": {"BaseDirectory": self.repobase}}) self.repouser=database.User(username=u"Tester", email=u"*****@*****.**", password=u"") database.getStore().add(self.repouser) database.getStore().commit()
def test_user_keys(self): u=database.User(username=u"user", password=u"", email=u"") for keyfile in self.pubkeys: with open(keyfile, "r") as fp: u.keys.add(database.UserSSHKey(name=unicode(keyfile), key=unicode(fp.read()))) database.getStore().add(u) database.getStore().commit() del u u=database.getStore().find(database.User).one() self.assertIsNotNone(u) self.assertEqual(u.keys.count(), len(self.pubkeys))
def setUp(self): super(TestTeamMembershipModel, self).setUp() self.repo_owner=database.Team(username=u"Tester") self.repo_user=database.User(username=u"Tester2", email=u"*****@*****.**", password=u"") self.other_user=database.User(username=u"Tester3", email=u"*****@*****.**", password=u"") self.repo=database.Repository(name=u"test-repo", description=u"Testing repo", public=False) self.repo_owner.repositories.add(self.repo) database.getStore().add(self.repo_owner) database.getStore().add(self.repo_user) database.getStore().add(self.other_user) database.getStore().add(self.repo) database.getStore().commit()
def test_push_other_private_repo_with_access(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) repositories=database.getStore().find(database.Repository) self.assertGreater(repositories.count(), 0) for u in users: self.assertGreater(u.keys.count(), 0) self.assertGreater(u.repositories.count(), 0) key=None for _key in u.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] for r in repositories: if r.getAccess(u)==r.ACC_OWNER: continue r.public=False r.setAccess(u, r.ACC_PUSH) database.getStore().commit() clonedir="%s_%d"%(self.repo_clone_dir, r.repository_id) #clone the repo self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n"%(r.name, r.description)) #make, commit, and push changes with open(readme, "a") as fp: fp.write("%s\n"%(r.name,)) curdir=os.getcwd() os.chdir(clonedir) self.assertEqual(self._shell("git commit -am \"Test commit\""), 0) self.assertEqual(self._shell("git push --all", env={"GIT_SSH_KEY": keyfile}), 0) os.chdir(curdir) #Remove all traces, re-clone and verify shutil.rmtree(clonedir) self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n%s\n"%(r.name, r.description, r.name)) shutil.rmtree(clonedir)
def test_clone_team_private_repo_with_access(self): self.test_team_repo.public=False users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) user=None for u in users: user=u break self.test_team.setAccess(user, database.Team.ACC_VIEW) self.assertGreater(user.keys.count(), 0) key=None for _key in user.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] clonedir="%s_%d"%(self.repo_clone_dir, self.test_team_repo.repository_id) self.assertEqual( self._shell("git clone %s %s"%(self.test_team_repo.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n"%(self.test_team_repo.name, self.test_team_repo.description)) shutil.rmtree(clonedir)
def test_create_repo_readme(self): repo=database.Repository(name=u"test-repo", description=u"Testing Repo") self.repouser.repositories.add(repo) repo.setPath() database.getStore().commit() repo.create(add_readme=True) self.assertTrue(os.path.exists(repo.getRepositoryDir())) curdir=os.getcwd() os.chdir(self.repoclonedir) try: subprocess.check_call([gitastic.config.get("Repository/Git", do_except=True), "clone", repo.getRepositoryDir(), repo.getRepositoryDir().split("/").pop()]) readme=os.path.join(self.repoclonedir, repo.getRepositoryDir().split("/").pop(), "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# test-repo\n\nTesting Repo\n") finally: os.chdir(curdir)
def test_push_team_repo_with_access(self): self.test_team_repo.public=False users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) user=None for u in users: user=u break self.test_team.setAccess(user, database.Team.ACC_MODERATE) self.assertGreater(user.keys.count(), 0) key=None for _key in user.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] clonedir="%s_%d"%(self.repo_clone_dir, self.test_team_repo.repository_id) #clone the repo self.assertEqual( self._shell("git clone %s %s"%(self.test_team_repo.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n"%(self.test_team_repo.name, self.test_team_repo.description)) #make, commit, and push changes with open(readme, "a") as fp: fp.write("%s\n"%(self.test_team_repo.name,)) curdir=os.getcwd() os.chdir(clonedir) self.assertEqual(self._shell("git commit -am \"Test commit\""), 0) self.assertEqual(self._shell("git push --all", env={"GIT_SSH_KEY": keyfile}), 0) os.chdir(curdir) #Remove all traces, re-clone and verify shutil.rmtree(clonedir) self.assertEqual( self._shell("git clone %s %s"%(self.test_team_repo.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n%s\n"%(self.test_team_repo.name, self.test_team_repo.description, self.test_team_repo.name)) shutil.rmtree(clonedir)
def test_clone_invalid_key(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) for u in users: self.assertGreater(u.repositories.count(), 0) for r in u.repositories: for kinfo in self.client_keys: if kinfo["valid"]: continue keyfile=os.path.join(self.ssh_path, kinfo["keyfile"]) clonedir="%s_%d"%(self.repo_clone_dir, r.repository_id) self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 128 ) self.assertFalse(os.path.exists(clonedir))
def test_clone_team_public_repo(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) user=None for u in users: user=u break self.assertGreater(user.keys.count(), 0) key=None for _key in user.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] clonedir="%s_%d"%(self.repo_clone_dir, self.test_team_repo.repository_id) self.assertEqual( self._shell("git clone %s %s"%(self.test_team_repo.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 128 )
def test_clone(self): users=database.getStore().find(database.User) self.assertGreater(users.count(), 0) for u in users: self.assertGreater(u.keys.count(), 0) self.assertGreater(u.repositories.count(), 0) key=None for _key in u.keys: key=_key break keyfile=self.keyfile_map[key.user_ssh_key_id] for r in u.repositories: clonedir="%s_%d"%(self.repo_clone_dir, r.repository_id) self.assertEqual( self._shell("git clone %s %s"%(r.getRepositoryCloneURI(), clonedir), env={"GIT_SSH_KEY": keyfile}), 0 ) readme=os.path.join(clonedir, "README.md") self.assertTrue(os.path.exists(os.path.dirname(readme))) self.assertTrue(os.path.exists(readme)) with open(readme, "r") as fp: self.assertEqual(fp.read(), "# %s\n\n%s\n"%(r.name, r.description)) shutil.rmtree(clonedir)
def test_create_duplicate(self): repo1=database.Repository(name=u"test-repo", description=u"Testing Repo") self.repouser.repositories.add(repo1) repo1.setPath() database.getStore().commit() repo1.create() with self.assertRaises(IntegrityError): repo2=database.Repository(name=u"test-repo", description=u"Testing Repo") self.repouser.repositories.add(repo2) repo2.setPath() database.getStore().commit() repo3=database.Repository(name=u"test-repo3", description=u"Testing Repo") self.repouser.repositories.add(repo3) repo3.setPath() os.makedirs(repo3.getRepositoryDir()) with self.assertRaises(database.RepositoryError): repo3.create() database.getStore().rollback()
def test_create_duplicate(self): team1=database.Team(name=u"Test-team1") database.getStore().add(team1) database.getStore().commit() team2=database.Team(name=u"Test-team2") database.getStore().add(team2) database.getStore().commit() with self.assertRaises(IntegrityError): team3=database.Team(name=u"Test-team2") database.getStore().add(team3) database.getStore().commit()
def setUp(self): #init the database self._drop_tables() subprocess.call([os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), "gitastic", "update-db")), gitastic.config.get("DatabaseURI")]) #init paths self.sshd=subprocess.check_output("which sshd", shell=True).strip() self.ssh_path=os.path.join(os.path.abspath(os.path.dirname(__file__)), "ssh") self.host_key=os.path.join(self.ssh_path, "TESTING_ONLY_host_rsa") self.client_keys=[ {"keyfile": "TESTING_ONLY_client_rsa", "valid": True}, {"keyfile": "TESTING_ONLY_client_rsa_2", "valid": True}, {"keyfile": "TESTING_ONLY_client_rsa_invalid", "valid": False}, ] self.sshd_config=os.path.join(self.ssh_path, "sshd_config") #find a port on this machine that is not in use for the sshd self.sshd_port=None for candidatePort in range(2000, 3000): s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) res=s.connect_ex(("127.0.0.1", candidatePort)) if res==0: s.close() continue self.sshd_port=candidatePort break #sanity checks - we have to have an sshd and keys for testing self.assertNotEqual(self.sshd, "", "Missing SSHD (ensure 'which sshd' returns something)") self.assertTrue(os.path.isfile(self.host_key), "Missing host key at %s"%(self.host_key,)) self.assertTrue(os.path.isfile(self.host_key+".pub"), "Missing host pubkey at %s"%(self.host_key+".pub",)) self.assertIsNotNone(self.sshd_port, "Could not find suitable port to start SSHD on") #Set up a temp dir to hold everything (makes for easy cleanup) self.temp_dir=tempfile.mkdtemp() #Write out an alternate configuration self.config_dir=os.path.join(self.temp_dir, "config") os.makedirs(self.config_dir) subprocess.check_call("cp -rf %s/* %s/"%(os.path.join(os.path.dirname(__file__), "config"), self.config_dir), shell=True) with open(os.path.join(self.config_dir, "testing_config.yml"), "w") as fp: fp.write(yaml.dump({"Repository": {"BaseDirectory": self.temp_dir}})) gitastic.config.load(os.path.join(self.config_dir, "testing_config.yml")) #fix permissions for ssh dirs subprocess.check_call(["/bin/chown", "-R", getpass.getuser(), self.temp_dir]) subprocess.check_call(["/bin/chmod", "-R", "0700", self.temp_dir]) #set up authorized_keys so sshd will let users log in self.ssh_home_dir=os.path.join(self.temp_dir, "ssh_temp_home", getpass.getuser()) self.ssh_authorized_keys=os.path.join(self.ssh_home_dir, ".ssh", "authorized_keys") os.makedirs(os.path.join(self.ssh_home_dir, ".ssh")) #generate authorized_keys file self.keyfile_map={} gitasticshell=os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), "gitastic", "gitastic-shell") with open(self.ssh_authorized_keys, "w") as fp_auth: for i, kinfo in enumerate(self.client_keys): if not kinfo["valid"]: continue with open(os.path.join(self.ssh_path, kinfo["keyfile"]+".pub"), "r") as fp_key: keydata=fp_key.readline() #To get a valid key ID we need to add it to the db u=database.User(username=u"%s_%d"%(keydata.split().pop(), i), email=u"*****@*****.**", password=u".") k=database.UserSSHKey(user=u, name=unicode(keydata.split().pop()), key=unicode(keydata)) database.getStore().add(u) database.getStore().add(k) database.getStore().commit() self.keyfile_map[k.user_ssh_key_id]=os.path.join(self.ssh_path, kinfo["keyfile"]) fp_auth.write("command=\"%s %d %s\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s\n"%( gitasticshell, k.user_ssh_key_id, self.config_dir, keydata)) subprocess.check_call(["/bin/chmod", "0600", self.ssh_authorized_keys]) #later we set this path as $HOME #set up path for known_hosts self.known_hosts_file=os.path.join(self.temp_dir, "ssh_known_hosts") #init a git repo to clone self.repo_clone_dir=os.path.join(self.temp_dir, "gitclone") #don't create the dir into which we clone or git will bail self.assertFalse(os.path.exists(self.repo_clone_dir)) #we'll create the same repo for each user for u in database.getStore().find(database.User): r=database.Repository(name=u"test_repo", description=u"This is a testing repository") u.repositories.add(r) r.setPath() r.create(add_readme=True) database.getStore().commit() #Set up infrastructure for testing team repos self.test_team=database.Team(name=u"Test-team") database.getStore().add(self.test_team) database.getStore().commit() self.test_team_repo=database.Repository(name=u"test_repo", description=u"This is a testing repository") self.test_team.repositories.add(self.test_team_repo) database.getStore().commit() self.test_team_repo.setPath() self.test_team_repo.create(add_readme=True) database.getStore().add(self.test_team_repo) database.getStore().commit() #setup the environment for commands to be run self.shell_env={ #We change the ssh key frequently so we can't specify it here "GIT_SSH": os.path.join(self.ssh_path, "git_ssh_wrapper.sh"), "SSH_KNOWN_HOSTS": self.known_hosts_file, "SSH_PORT": str(self.sshd_port), "HOME": self.ssh_home_dir, "SSH_VERBOSE": "-v -v -v" if self.ssh_debug else "" } #start up the sshd self._stop_sshd=threading.Event() self._sshd_thread=threading.Thread(target=self._run_sshd) self._sshd_thread.start() #let the sshd start up time.sleep(1) #now make sure the sshd is accepting connections or we can't keep testing s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) res=s.connect_ex(("127.0.0.1", self.sshd_port)) s.close() self.assertEqual(res, 0, "The test SSHD is not accepting connections") #Generate known_hosts from the ssh server we just started with open(self.known_hosts_file, "w") as fp: for line in subprocess.check_output("ssh-keyscan -H -t rsa -p %d 127.0.0.1"%(self.sshd_port,), shell=True).split("\n"): if line.startswith("#"): continue fp.write(line) fp.write("\n")
def _drop_tables(self): database.getStore().execute("SET FOREIGN_KEY_CHECKS = 0;") for table in database.getStore().execute("show tables;"): database.getStore().execute("drop table %s;"%(table[0],)) database.getStore().execute("SET FOREIGN_KEY_CHECKS = 1;")