Rescoped colead role and revised session handling.
This commit is contained in:
parent
da5f3524fa
commit
7dbcd05262
12 changed files with 376 additions and 50 deletions
|
|
@ -12,20 +12,19 @@ func (app *App) handleListVolunteers(w http.ResponseWriter, r *http.Request) {
|
|||
search := q.Get("search")
|
||||
since := q.Get("since")
|
||||
|
||||
var deptID *int
|
||||
var deptIDs []int
|
||||
if d := q.Get("dept"); d != "" {
|
||||
id, err := strconv.Atoi(d)
|
||||
if err == nil {
|
||||
deptID = &id
|
||||
if id, err := strconv.Atoi(d); err == nil {
|
||||
deptIDs = []int{id}
|
||||
}
|
||||
}
|
||||
|
||||
claims := claimsFromContext(r)
|
||||
if hasAnyRole(claims.Roles, []string{"colead"}) && !hasAnyRole(claims.Roles, []string{"admin", "staffing"}) && deptID == nil && len(claims.DeptIDs) > 0 {
|
||||
deptID = &claims.DeptIDs[0]
|
||||
if isCoLeadOnly(claims) && len(deptIDs) == 0 {
|
||||
deptIDs = claims.DeptIDs
|
||||
}
|
||||
|
||||
volunteers, err := app.listVolunteers(search, deptID, since)
|
||||
volunteers, err := app.listVolunteers(search, deptIDs, since)
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -55,7 +54,7 @@ func (app *App) handleCreateVolunteer(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if hasAnyRole(claims.Roles, []string{"colead"}) && !hasAnyRole(claims.Roles, []string{"admin", "staffing"}) {
|
||||
if isCoLeadOnly(claims) {
|
||||
if body.DepartmentID == nil || !inSlice(*body.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
|
|
@ -127,12 +126,16 @@ func (app *App) handleUpdateVolunteer(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if hasAnyRole(claims.Roles, []string{"colead"}) && !hasAnyRole(claims.Roles, []string{"admin", "staffing"}) {
|
||||
if isCoLeadOnly(claims) {
|
||||
existing, _ := app.getVolunteer(id)
|
||||
if existing == nil || existing.DepartmentID == nil || !inSlice(*existing.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if body.DepartmentID != nil && !inSlice(*body.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: cannot move volunteer to that department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
v := Volunteer{
|
||||
ID: id,
|
||||
|
|
@ -157,6 +160,14 @@ func (app *App) handleDeleteVolunteer(w http.ResponseWriter, r *http.Request) {
|
|||
writeError(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if isCoLeadOnly(claims) {
|
||||
v, _ := app.getVolunteer(id)
|
||||
if v == nil || v.DepartmentID == nil || !inSlice(*v.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := app.deleteVolunteer(id); err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -171,6 +182,13 @@ func (app *App) handleMarkVolunteerReady(w http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if isCoLeadOnly(claims) {
|
||||
v, _ := app.getVolunteer(id)
|
||||
if v == nil || v.DepartmentID == nil || !inSlice(*v.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
v, err := app.markVolunteerReady(id, claims.ParticipantID)
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
|
|
@ -186,6 +204,14 @@ func (app *App) handleConfirmVolunteer(w http.ResponseWriter, r *http.Request) {
|
|||
writeError(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if isCoLeadOnly(claims) {
|
||||
v, _ := app.getVolunteer(id)
|
||||
if v == nil || v.DepartmentID == nil || !inSlice(*v.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
v, err := app.confirmVolunteer(id)
|
||||
if err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
|
|
@ -207,7 +233,24 @@ func (app *App) handleAssignShift(w http.ResponseWriter, r *http.Request) {
|
|||
writeError(w, "shift_id required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if err := app.assignShift(volunteerID, body.ShiftID); err != nil {
|
||||
claims := claimsFromContext(r)
|
||||
if isCoLeadOnly(claims) {
|
||||
v, _ := app.getVolunteer(volunteerID)
|
||||
if v == nil || v.DepartmentID == nil || !inSlice(*v.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
shift, err := app.getShift(body.ShiftID)
|
||||
if err != nil || shift == nil {
|
||||
writeError(w, "shift not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err := app.assignShiftWithCapacity(volunteerID, body.ShiftID, shift.Capacity); err != nil {
|
||||
if err == errShiftFull {
|
||||
writeError(w, "shift is at capacity", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
|
@ -225,6 +268,14 @@ func (app *App) handleUnassignShift(w http.ResponseWriter, r *http.Request) {
|
|||
writeError(w, "invalid shift id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
claims := claimsFromContext(r)
|
||||
if isCoLeadOnly(claims) {
|
||||
v, _ := app.getVolunteer(volunteerID)
|
||||
if v == nil || v.DepartmentID == nil || !inSlice(*v.DepartmentID, claims.DeptIDs) {
|
||||
writeError(w, "forbidden: outside your department", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := app.unassignShift(volunteerID, shiftID); err != nil {
|
||||
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
@ -232,11 +283,3 @@ func (app *App) handleUnassignShift(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func inSlice(v int, s []int) bool {
|
||||
for _, x := range s {
|
||||
if x == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue