Exemple #1
0
func TestIsMemberAdmin(t *testing.T) {
	Setup()
	defer Teardown()

	// expecting user is Owner
	if ok, err := database.IsMemberAdmin(1, 1); err != nil {
		t.Error(err)
	} else if !ok {
		t.Errorf("Expected IsMemberAdmin to return true, returned false")
	}

	// expecting user is Admin
	if ok, err := database.IsMemberAdmin(2, 1); err != nil {
		t.Error(err)
	} else if !ok {
		t.Errorf("Expected IsMemberAdmin to return true, returned false")
	}

	// expecting user is NOT Admin (Write role)
	if ok, err := database.IsMemberAdmin(3, 1); err != nil {
		t.Error(err)
	} else if ok {
		t.Errorf("Expected IsMemberAdmin to return false, returned true")
	}
}
Exemple #2
0
func (h RepoAdminHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	user, err := readUser(r)
	if err != nil {
		redirectLogin(w, r)
		return
	}

	// repository name from the URL parameters
	hostParam := r.FormValue(":host")
	userParam := r.FormValue(":owner")
	nameParam := r.FormValue(":name")
	repoName := fmt.Sprintf("%s/%s/%s", hostParam, userParam, nameParam)

	repo, err := database.GetRepoSlug(repoName)
	if err != nil {
		RenderNotFound(w)
		return
	}

	// The User must own the repository OR be a member
	// of the Team that owns the repository.
	if user.ID != repo.UserID {
		if admin, _ := database.IsMemberAdmin(user.ID, repo.TeamID); admin == false {
			RenderNotFound(w)
			return
		}
	}

	if err = h(w, r, user, repo); err != nil {
		log.Print(err)
		RenderError(w, err, http.StatusBadRequest)
	}
}
Exemple #3
0
func (g *GitlabHandler) Create(w http.ResponseWriter, r *http.Request, u *User) error {
	teamName := r.FormValue("team")
	owner := r.FormValue("owner")
	name := r.FormValue("name")

	repo, err := g.newGitlabRepo(u, owner, name)
	if err != nil {
		return err
	}

	if len(teamName) > 0 {
		team, err := database.GetTeamSlug(teamName)
		if err != nil {
			return fmt.Errorf("Unable to find Team %s.", teamName)
		}

		// user must be an admin member of the team
		if ok, _ := database.IsMemberAdmin(u.ID, team.ID); !ok {
			return fmt.Errorf("Invalid permission to access Team %s.", teamName)
		}
		repo.TeamID = team.ID
	}

	// Save to the database
	if err := database.SaveRepo(repo); err != nil {
		return fmt.Errorf("Error saving repository to the database. %s", err)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #4
0
// Update a specific Team Member.
func TeamMemberUpdate(w http.ResponseWriter, r *http.Request, u *User) error {
	roleParam := r.FormValue("Role")
	teamParam := r.FormValue(":team")

	// get the team from the database
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderError(w, err, http.StatusNotFound)
	}
	// verify the user is a admin member of the team
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return RenderError(w, err, http.StatusNotFound)
	}

	// add the user to the team
	if err := database.SaveMember(user.ID, team.ID, roleParam); err != nil {
		return RenderError(w, err, http.StatusInternalServerError)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #5
0
// Return an HTML form for editing a Team Member.
func TeamMemberEdit(w http.ResponseWriter, r *http.Request, u *User) error {
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return err
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	user, err := database.GetUser(int64(id))
	if err != nil {
		return err
	}
	member, err := database.GetMember(user.ID, team.ID)
	if err != nil {
		return err
	}
	data := struct {
		User   *User
		Team   *Team
		Member *Member
	}{u, team, member}
	return RenderTemplate(w, "members_edit.html", &data)
}
Exemple #6
0
// Return an HTML form for editing a Team.
func TeamEdit(w http.ResponseWriter, r *http.Request, u *User) error {
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return err
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}
	data := struct {
		User *User
		Team *Team
	}{u, team}
	return RenderTemplate(w, "team_profile.html", &data)
}
Exemple #7
0
// Updates an existing repository.
func RepoUpdate(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error {
	switch r.FormValue("action") {
	case "params":
		repo.Params = map[string]string{}
		if err := goyaml.Unmarshal([]byte(r.FormValue("params")), &repo.Params); err != nil {
			return err
		}
	default:
		repo.URL = r.FormValue("URL")
		repo.Disabled = len(r.FormValue("Disabled")) == 0
		repo.DisabledPullRequest = len(r.FormValue("DisabledPullRequest")) == 0
		repo.Private = len(r.FormValue("Private")) > 0
		repo.Privileged = u.Admin && len(r.FormValue("Privileged")) > 0

		// value of "" indicates the currently authenticated user
		// should be set as the administrator.
		if len(r.FormValue("Owner")) == 0 {
			repo.UserID = u.ID
			repo.TeamID = 0
		} else {
			// else the user has chosen a team
			team, err := database.GetTeamSlug(r.FormValue("Owner"))
			if err != nil {
				return err
			}

			// verify the user is a member of the team
			if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
				return fmt.Errorf("Forbidden")
			}

			// set the team ID
			repo.TeamID = team.ID
		}
	}

	// save the page
	if err := database.SaveRepo(repo); err != nil {
		return err
	}

	http.Redirect(w, r, r.URL.Path, http.StatusSeeOther)
	return nil
}
Exemple #8
0
// Delete a specific Team.
func TeamDelete(w http.ResponseWriter, r *http.Request, u *User) error {
	// get the team from the database
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderNotFound(w)
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}
	// the user must confirm their password before deleting
	password := r.FormValue("password")
	if err := u.ComparePassword(password); err != nil {
		return RenderError(w, err, http.StatusBadRequest)
	}

	database.DeleteTeam(team.ID)
	http.Redirect(w, r, "/account/user/teams", http.StatusSeeOther)
	return nil
}
Exemple #9
0
// Display a list of Team Members.
func TeamMembers(w http.ResponseWriter, r *http.Request, u *User) error {
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return err
	}
	// user must be a team member admin
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}
	members, err := database.ListMembers(team.ID)
	if err != nil {
		return err
	}
	data := struct {
		User    *User
		Team    *Team
		Members []*Member
	}{u, team, members}
	return RenderTemplate(w, "team_members.html", &data)
}
Exemple #10
0
// Update a specific Team.
func TeamUpdate(w http.ResponseWriter, r *http.Request, u *User) error {
	// get team from the database
	teamName := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamName)
	if err != nil {
		return fmt.Errorf("Forbidden")
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	team.Name = r.FormValue("name")
	team.SetEmail(r.FormValue("email"))

	if err := team.Validate(); err != nil {
		return RenderError(w, err, http.StatusBadRequest)
	}
	if err := database.SaveTeam(team); err != nil {
		return RenderError(w, err, http.StatusBadRequest)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #11
0
// Invite a new Team Member.
func TeamMemberInvite(w http.ResponseWriter, r *http.Request, u *User) error {
	teamParam := r.FormValue(":team")
	mailParam := r.FormValue("email")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderError(w, err, http.StatusNotFound)
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// generate a token that is valid for 3 days to join the team
	token := authcookie.New(strconv.Itoa(int(team.ID)), time.Now().Add(72*time.Hour), secret)

	// hostname from settings
	hostname := database.SettingsMust().URL().String()
	emailEnabled := database.SettingsMust().SmtpServer != ""

	if !emailEnabled {
		// Email is not enabled, so must let the user know the signup link
		link := fmt.Sprintf("%v/accept?token=%v", hostname, token)
		return RenderText(w, link, http.StatusOK)
	}

	// send the invitation
	data := struct {
		User  *User
		Team  *Team
		Token string
		Host  string
	}{u, team, token, hostname}

	// send email async
	go mail.SendInvitation(team.Name, mailParam, &data)

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #12
0
// Delete a specific Team Member.
func TeamMemberDelete(w http.ResponseWriter, r *http.Request, u *User) error {
	// get the team from the database
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderNotFound(w)
	}

	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return RenderNotFound(w)
	}
	// must be at least 1 member
	members, err := database.ListMembers(team.ID)
	if err != nil {
		return err
	} else if len(members) == 1 {
		return fmt.Errorf("There must be at least 1 member per team")
	}
	// delete the member
	database.DeleteMember(user.ID, team.ID)
	http.Redirect(w, r, fmt.Sprintf("/account/team/%s/members", team.Name), http.StatusSeeOther)
	return nil
}
Exemple #13
0
func RepoCreateGithub(w http.ResponseWriter, r *http.Request, u *User) error {
	teamName := r.FormValue("team")
	owner := r.FormValue("owner")
	name := r.FormValue("name")

	// get the github settings from the database
	settings := database.SettingsMust()

	// create the GitHub client
	client := github.New(u.GithubToken)
	githubRepo, err := client.Repos.Find(owner, name)
	if err != nil {
		return err
	}

	repo, err := NewGitHubRepo(owner, name, githubRepo.Private)
	if err != nil {
		return err
	}

	repo.UserID = u.ID
	repo.Private = githubRepo.Private

	// if the user chose to assign to a team account
	// we need to retrieve the team, verify the user
	// has access, and then set the team id.
	if len(teamName) > 0 {
		team, err := database.GetTeamSlug(teamName)
		if err != nil {
			log.Printf("error retrieving team %s", teamName)
			return err
		}

		// user must be an admin member of the team
		if ok, _ := database.IsMemberAdmin(u.ID, team.ID); !ok {
			return fmt.Errorf("Forbidden")
		}

		repo.TeamID = team.ID
	}

	// if the repository is private we'll need
	// to upload a github key to the repository
	if repo.Private {
		// name the key
		keyName := fmt.Sprintf("%s@%s", repo.Owner, settings.Domain)

		// create the github key, or update if one already exists
		_, err := client.RepoKeys.CreateUpdate(owner, name, repo.PublicKey, keyName)
		if err != nil {
			return fmt.Errorf("Unable to add Private Key to your GitHub repository")
		}
	} else {

	}

	// create a hook so that we get notified when code
	// is pushed to the repository and can execute a build.
	link := fmt.Sprintf("%s://%s/hook/github.com?id=%s", settings.Scheme, settings.Domain, repo.Slug)

	// add the hook
	if _, err := client.Hooks.CreateUpdate(owner, name, link); err != nil {
		return fmt.Errorf("Unable to add Hook to your GitHub repository. %s", err.Error())
	}

	// Save to the database
	if err := database.SaveRepo(repo); err != nil {
		log.Print("error saving new repository to the database")
		return err
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #14
0
func RepoCreateBitbucket(w http.ResponseWriter, r *http.Request, u *User) error {
	teamName := r.FormValue("team")
	owner := r.FormValue("owner")
	name := r.FormValue("name")

	// get the bitbucket settings from the database
	settings := database.SettingsMust()

	// create the Bitbucket client
	client := bitbucket.New(
		settings.BitbucketKey,
		settings.BitbucketSecret,
		u.BitbucketToken,
		u.BitbucketSecret,
	)

	bitbucketRepo, err := client.Repos.Find(owner, name)
	if err != nil {
		return fmt.Errorf("Unable to find Bitbucket repository %s/%s.", owner, name)
	}

	repo, err := NewBitbucketRepo(owner, name, bitbucketRepo.Private)
	if err != nil {
		return err
	}

	repo.UserID = u.ID
	repo.Private = bitbucketRepo.Private

	// if the user chose to assign to a team account
	// we need to retrieve the team, verify the user
	// has access, and then set the team id.
	if len(teamName) > 0 {
		team, err := database.GetTeamSlug(teamName)
		if err != nil {
			return fmt.Errorf("Unable to find Team %s.", teamName)
		}

		// user must be an admin member of the team
		if ok, _ := database.IsMemberAdmin(u.ID, team.ID); !ok {
			return fmt.Errorf("Invalid permission to access Team %s.", teamName)
		}

		repo.TeamID = team.ID
	}

	// if the repository is private we'll need
	// to upload a bitbucket key to the repository
	if repo.Private {
		// name the key
		keyName := fmt.Sprintf("%s@%s", repo.Owner, settings.Domain)

		// create the bitbucket key, or update if one already exists
		_, err := client.RepoKeys.CreateUpdate(owner, name, repo.PublicKey, keyName)
		if err != nil {
			return fmt.Errorf("Unable to add Public Key to your Bitbucket repository: %s", err)
		}
	} else {

	}

	// create a hook so that we get notified when code
	// is pushed to the repository and can execute a build.
	link := fmt.Sprintf("%s://%s/hook/bitbucket.org?id=%s", settings.Scheme, settings.Domain, repo.Slug)

	// add the hook
	if _, err := client.Brokers.CreateUpdate(owner, name, link, bitbucket.BrokerTypePost); err != nil {
		return fmt.Errorf("Unable to add Hook to your Bitbucket repository. %s", err.Error())
	}

	// Save to the database
	if err := database.SaveRepo(repo); err != nil {
		return fmt.Errorf("Error saving repository to the database. %s", err)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Exemple #15
0
func RepoCreateGithubLimited(w http.ResponseWriter, r *http.Request, u *User) error {
	teamName := r.FormValue("team")
	owner := r.FormValue("owner")
	name := r.FormValue("name")

	readToken := r.FormValue("read-token")
	writeToken := r.FormValue("write-token")

	u.GithubToken = readToken
	u.GithubWriteToken = writeToken

	// get the github settings from the database
	settings := database.SettingsMust()
	fmt.Printf("got settings: %s\n", settings)

	// create the GitHub client
	rClient := github.New(readToken)
	wClient := github.New(writeToken)
	rClient.ApiUrl = settings.GitHubApiUrl
	wClient.ApiUrl = settings.GitHubApiUrl

	githubRepo, err := rClient.Repos.Find(owner, name)
	if err != nil {
		fmt.Printf("err1, %s\n", err)
		return err
	}

	repo, err := NewGitHubRepo(settings.GitHubDomain, owner, name, githubRepo.Private)

	if err != nil {
		fmt.Printf("err2, %s\n", err)
		return err
	}

	repo.URL = fmt.Sprintf("https://%s@%s/%s/%s", readToken, settings.GitHubDomain, owner, name)

	repo.UserID = u.ID
	repo.Private = githubRepo.Private

	// if the user chose to assign to a team account
	// we need to retrieve the team, verify the user
	// has access, and then set the team id.
	if len(teamName) > 0 {
		team, err := database.GetTeamSlug(teamName)
		if err != nil {
			return fmt.Errorf("Unable to find Team %s.", teamName)
		}

		// user must be an admin member of the team
		if ok, _ := database.IsMemberAdmin(u.ID, team.ID); !ok {
			return fmt.Errorf("Invalid permission to access Team %s.", teamName)
		}
		repo.TeamID = team.ID
	}

	// create a hook so that we get notified when code                                                                                                                                                                                            // is pushed to the repository and can execute a build.
	link := fmt.Sprintf("%s://%s/hook/github.com?id=%s", settings.Scheme, settings.Domain, repo.Slug)

	// add the hook
	if _, err := wClient.Hooks.CreateUpdate(owner, name, link); err != nil {
		return fmt.Errorf("Unable to add Hook to your GitHub repository. %s", err.Error())
	}

	// Save to the database
	if err := database.SaveRepo(repo); err != nil {
		return fmt.Errorf("Error saving repository to the database. %s", err)
	}
	// Save user to the database
	if err := database.SaveUser(u); err != nil {
		return fmt.Errorf("Error saving user to the database. %s", err)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)

}