def create_submission(self, url_name, long_name, parent_project_url, owner): """ :param url_name: The urlname given by the user. Do not include /'es or username! """ # Form the git clone url (see functional requirements) submission_full_git_url = owner + "/submissions/" + url_name submission_db = self.mongo.gitsubmit.submissions project_db = self.mongo.gitsubmit.projects class_db = self.mongo.gitsubmit.classes # Make sure the url_name is unique shortname_check_doc = submission_db.find_one({"gitolite_url": submission_full_git_url}) if shortname_check_doc is not None: raise UrlNameAlreadyTakenError("That url name is already taken.") # Ensure the parent project exists parent_project_obj = project_db.find_one({"gitolite_url": parent_project_url}) if parent_project_obj is None: raise ProjectDoesNotExistError(str(parent_project_url)) parent_class_obj = class_db.find_one({"url_name": parent_project_obj["parent"]}) if parent_class_obj is None: raise ClassDoesNotExistError(str(parent_project_obj["parent"])) parent_class_url = parent_class_obj["url_name"] gw = GitoliteWrapper(self.glpath) # Make sure the owner exists gw.get_user_or_error(owner) # This is what actually causes the fork fork_callstring = "ssh git@" + self.ssh_host + " fork " + parent_project_url + " " + submission_full_git_url subprocess.call(fork_callstring, shell=True) # now create_repo sets the repo ACCESS rights in gitolite gw.create_repo(submission_full_git_url, owner) # If we got here, nothing went wrong, stuff it in the db submission_obj = {"gitolite_url": submission_full_git_url, "long_name": long_name, "owner": owner, "parent": parent_project_url, "contributors": [owner]} result = submission_db.insert_one(submission_obj) dest_dir = os.path.abspath(os.path.join(self.repo_root, submission_full_git_url+".git")) exists = os.path.exists(dest_dir) dest_file = os.path.join(dest_dir, "hooks", "pre-receive") src_hook = os.path.abspath(os.path.join("hooks", "pre-receive")) print "src", src_hook print "dest", dest_file print "exists", exists shutil.copy(src_hook, dest_file) return result
def remove_key_from_user(username): """ covered by 1_users / `User can delete an existing key from themselves` """ json_data = get_json_data() pkey = json_data.get("pkey") gw = GitoliteWrapper(GITOLITE_ADMIN_PATH) try: result = gw.remove_key_from_user_by_pretty_string(username, pkey) except KeyDoesNotExistError as e: return jsonify({"error": "Key does not exist for user!", "exception": str(e)}), 404 except CannotDeleteOnlyKeyError as e: return jsonify({"error": "Can't delete the only key on the account!", "exception": str(e)}), 400 if not result: return jsonify({"error": "Key was not found under user!", "exception": None}), 404 return list_ssh_keys(username)
def create_class(self, url_name, long_name, description, owner): class_db = self.mongo.gitsubmit.classes gw = GitoliteWrapper(self.glpath) # Make sure the owner exists gw.get_user_or_error(owner) # make sure urlname is unique shortname_check_doc = class_db.find_one({"url_name": url_name}) if shortname_check_doc is not None: raise UrlNameAlreadyTakenError("That url name is already taken.") class_obj = {"url_name": url_name, "long_name": long_name, "description": description, "owner": owner, "teachers": [owner], "students": []} return class_db.insert_one(class_obj)
def post_new_ssh_key(username): """ covered by 1_users / `User can add an ssh key` """ json_data = get_json_data() if False: # TODO: ensure that username exists return jsonify({"error": "username does not exist"}), 404 pkey_contents = json_data.get("pkey_contents") if not pkey_contents: return jsonify({"error": "No key was given!"}), 400 gw = GitoliteWrapper(GITOLITE_ADMIN_PATH) try: pretty_key_hex = gw.add_pkey_to_user(username, pkey_contents) return jsonify(key_added=pretty_key_hex) except InvalidKeyException as e: return jsonify({"error": "Public key was invalid format", "exception": str(e)}), 400 except KeyAlreadyExistsError as e: return jsonify({"error": "Public key already exists", "exception": str(e)}), 400 except UserDoesNotExistError as e: return jsonify({"error": "username not found!", "exception": str(e)}), 404
def create_project(self, url_name, long_name, description, parent_class_url_name, is_team_based, due_date, owner, max_team_size=4): """ :param url_name: The raw project url name. Do not include the parent class or /'es! """ # apply defaults in case None if max_team_size is None: max_team_size = 4 # form the git clone url (see functional requirements) gitolite_url = parent_class_url_name + "/" + url_name project_db = self.mongo.gitsubmit.projects class_db = self.mongo.gitsubmit.classes # Make sure the url_name is unique shortname_check_doc = project_db.find_one({"gitolite_url": gitolite_url}) if shortname_check_doc is not None: raise UrlNameAlreadyTakenError("That url name is already taken for that class.") # Ensure the parent class exists parent_class_obj = class_db.find_one({"url_name": parent_class_url_name}) if parent_class_obj is None: raise ClassDoesNotExistError(str(parent_class_url_name)) gw = GitoliteWrapper(self.glpath) # Make sure the owner exists gw.get_user_or_error(owner) # Add the teachers of the parent class to the project with RW permissions repo = gw.create_repo(gitolite_url, owner) for teacher in parent_class_obj["teachers"]: gw.give_user_readwrite_permission(teacher, repo.name) due_datetime = datetime.strptime(due_date, TIME_FORMAT) # If we've gotten here without exception, add to the DB project_obj = {"gitolite_url": gitolite_url, "url_name": url_name, "long_name": long_name, "description": description, "parent": parent_class_url_name, "is_team_based": is_team_based, "owner": owner, "due": due_datetime, "max_team_size": max_team_size} return project_db.insert_one(project_obj)
def convert_ssh_key_to_colon_string(key): hexstring = hashlib.md5(key.strip().split()[1]).hexdigest() colonstring = ':'.join(hexstring[i:i+2] for i in range(0, len(hexstring), 2)) return colonstring if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-p", "--mongo_port", help="the mongodb port to connect to", type=int) parser.add_argument("-s", "--ssh_host", help="the ssh host string to connect to") parser.add_argument("-pyo", "--pyolite_location", help="the folder pyolite should bind to") args = parser.parse_args() password = "******" dbw = DatabaseWrapper(args.pyolite_location, port=args.mongo_port, repositories_root="/var/lib/jenkins/jobs/acceptance-tests/workspace/temp") gw = GitoliteWrapper(args.pyolite_location) # give one user a REAL pubkey, so git can interact with server # note: this is the contents of /home/git/.ssh/test_key.pub and test_key2.pub test_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAObvHN/F6EX4L9/ExE4LdezTD1Dx/+fX0wZdropEyx63VxBn8HpgwVcjYq5fINAUAqtNoNpIgyXpp8RhoFv488qaCL9V7qwSf1Bnv5uaZ5lxIpdfEFXhu4JsgtdphMangwvSf2ADLASFdB99Sjxo/nxmjHsvyPZXuvYMNdmKn9ZBQyimUNpERlL4/ECVRoebnL4lD/+rzreacTiZA6KvPn8f7Xh8JNHwm9ndRCxflc8fTH+0VgkC2kpQVkWOoXqhQUQpX8fYxrmCamDG4oRAKJpF2SLkRv1OAv+jY58e2fxAUqFK/u2k6XFPn9Sxmz8pZsvp8OHAuVeSdECyoKw/J git@gitsubmit" test_key2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8DylxzTAc4y/AG/RCONTiZx2+2hfAgfuncXwZylUse6JkHKIIFbjkXqoAkmT0hsugMHb6IpnINcc41vXXOPTwjLrgMaO7r/eK6gs6rqUiVaJ3oVuJK9qw1PwPo/4O/eCQ3mtoDSm+U27/Q5D391jAuqngmMtYxQAUqS+Hv4/ORNbCNXl/b4UQYldUz3N2giNPCIXA78CCDwz4V/jOq6zejnt+DLoiBCTnCQWCIANX+Ij5pvqBP2pDtO9RnFVHEK1O2jXUHGiLq9AcLvDDYGnATwnXbXtPn5Ub0tLFcanO4DW93WTljhCS7TyzUq/MyAGwNmwi7OSVqpNYcHvhUg37 git@gitsubmit" # give the users some pkeys bogus_key = create_bogus_key() gw.add_pkey_to_user("student1", bogus_key["pubkey_contents"]) bogus_key2 = create_bogus_key() gw.add_pkey_to_user("student2", bogus_key2["pubkey_contents"]) bogus_key3 = create_bogus_key() gw.add_pkey_to_user("teacher1", bogus_key3["pubkey_contents"]) bogus_key4 = create_bogus_key() gw.add_pkey_to_user("teacher2", bogus_key4["pubkey_contents"])
def list_ssh_keys(username): """ covered by test 1_users / `Can list user's SSH keys` """ gw = GitoliteWrapper(GITOLITE_ADMIN_PATH) if not gw.user_exists(username): return jsonify({"error": "username not found!", "exception": None}), 404 return jsonify(keys=gw.get_list_of_pretty_key_strings(username))