internal/httpd/orgweb.go

0338e6ace3de199d5fc383852649919b68ef3e42
gitbay/internal/httpd/orgweb.go history · blame · raw

120 lines · 3586 bytes

  1package httpd
  2
  3import (
  4	"net/http"
  5	"strings"
  6
  7	"gitbay.org/gitbay/internal/store"
  8)
  9
 10// teamView is a team with the two things an admin needs to see about it:
 11// who is in it and what it reaches.
 12type teamView struct {
 13	Name    string
 14	Members []string
 15	Grants  []store.TeamGrant
 16}
 17
 18// orgAdminView gathers the management state for an organization page. It
 19// returns ok=false for user pages and for viewers who do not administer the
 20// org, so the page renders read-only for everyone else.
 21func (s *Server) orgAdminView(viewer store.User, kind, name string) (teams []teamView, ok bool) {
 22	if kind != "org" || viewer.ID == 0 {
 23		return nil, false
 24	}
 25	org, err := s.st.OrgByName(name)
 26	if err != nil {
 27		return nil, false
 28	}
 29	if role, _ := s.st.OrgRole(org.ID, viewer.ID); role != "admin" {
 30		return nil, false
 31	}
 32	list, _ := s.st.ListTeams(org.ID)
 33	for _, t := range list {
 34		members, _ := s.st.TeamMembers(t.ID)
 35		grants, _ := s.st.TeamGrants(t.ID)
 36		teams = append(teams, teamView{Name: t.Name, Members: members, Grants: grants})
 37	}
 38	return teams, true
 39}
 40
 41// orgSubmit routes the organization forms on an owner page. Every branch
 42// dispatches the matching control command, so membership rules and audit
 43// entries stay in one implementation.
 44func (s *Server) orgSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
 45	owner := r.PathValue("owner")
 46	// The member and team forms live on the profile's people tab (#242),
 47	// which is where a result has to land for its flash to render.
 48	back := func(msg string) {
 49		s.setFlash(w, msg)
 50		http.Redirect(w, r, "/"+owner+"/-/people", http.StatusSeeOther)
 51	}
 52	field := r.FormValue("field")
 53	team := strings.TrimSpace(r.FormValue("team"))
 54	user := strings.TrimSpace(r.FormValue("user"))
 55
 56	// Create and rename land on a different page than the one they were
 57	// posted from: a new org has no page yet, and a renamed one has moved.
 58	switch field {
 59	case "org-create", "org-rename":
 60		name := strings.TrimSpace(r.FormValue("name"))
 61		argv := []string{"org", "create", name}
 62		if field == "org-rename" {
 63			argv = []string{"org", "rename", owner, name}
 64		}
 65		if _, msg, ok := s.runControl(u, argv); !ok {
 66			back(msg)
 67			return
 68		}
 69		http.Redirect(w, r, "/"+name, http.StatusSeeOther)
 70		return
 71	}
 72
 73	var argv []string
 74	switch field {
 75	case "member-add":
 76		argv = []string{"org", "members", "add", owner, user}
 77		if role := r.FormValue("role"); role == "admin" || role == "member" {
 78			argv = append(argv, "--role", role)
 79		}
 80	case "member-remove":
 81		if ok, msg := confirmed(r, user); !ok {
 82			back(msg)
 83			return
 84		}
 85		argv = []string{"org", "members", "remove", owner, user}
 86	case "team-create":
 87		argv = []string{"org", "team", "create", owner, team}
 88	case "team-delete":
 89		if ok, msg := confirmed(r, team); !ok {
 90			back(msg)
 91			return
 92		}
 93		argv = []string{"org", "team", "delete", owner, team}
 94	case "team-add":
 95		argv = append([]string{"org", "team", "add", owner, team}, strings.Fields(user)...)
 96	case "team-remove":
 97		if ok, msg := confirmed(r, team); !ok {
 98			back(msg)
 99			return
100		}
101		argv = append([]string{"org", "team", "remove", owner, team}, strings.Fields(user)...)
102	case "team-grant":
103		argv = []string{"org", "team", "grant", owner, team,
104			strings.TrimSpace(r.FormValue("repo")), r.FormValue("role")}
105	case "team-revoke":
106		if ok, msg := confirmed(r, team); !ok {
107			back(msg)
108			return
109		}
110		argv = []string{"org", "team", "revoke", owner, team, strings.TrimSpace(r.FormValue("repo"))}
111	default:
112		back("unknown form")
113		return
114	}
115	if _, msg, ok := s.runControl(u, argv); !ok {
116		back(msg)
117		return
118	}
119	back("")
120}