Allow managers to view subordinate PF projects
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package pf
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
@@ -111,7 +112,16 @@ func (s Server) accessMe(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s Server) summary(w http.ResponseWriter, r *http.Request) {
|
||||
emp, err := s.App.CurrentEmployee(r.Context(), portalUserID(r), false)
|
||||
var emp *Employee
|
||||
var err error
|
||||
if requested := ownerPortalIDFromQuery(r); requested != nil {
|
||||
var ok bool
|
||||
emp, ok = s.resolveProjectOwnerForRead(w, r, requested)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
emp, err = s.App.CurrentEmployee(r.Context(), portalUserID(r), false)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -119,6 +129,7 @@ func (s Server) summary(w http.ResponseWriter, r *http.Request) {
|
||||
if emp != nil && emp.TGChatID == nil {
|
||||
emp = nil
|
||||
}
|
||||
}
|
||||
out, err := s.App.Summary(r.Context(), emp)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
@@ -226,7 +237,13 @@ func (s Server) employeeItem(w http.ResponseWriter, r *http.Request, path string
|
||||
func (s Server) projects(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
emp, ok := s.requireEmployee(w, r)
|
||||
var emp *Employee
|
||||
var ok bool
|
||||
if requested := ownerPortalIDFromQuery(r); requested != nil {
|
||||
emp, ok = s.resolveProjectOwnerForRead(w, r, requested)
|
||||
} else {
|
||||
emp, ok = s.requireEmployee(w, r)
|
||||
}
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -439,6 +456,27 @@ func (s Server) resolveProjectOwner(w http.ResponseWriter, r *http.Request, requ
|
||||
return owner, true
|
||||
}
|
||||
|
||||
func (s Server) resolveProjectOwnerForRead(w http.ResponseWriter, r *http.Request, requested *string) (*Employee, bool) {
|
||||
if requested == nil || strings.TrimSpace(*requested) == "" {
|
||||
return s.requireEmployee(w, r)
|
||||
}
|
||||
targetPortalID := strings.TrimSpace(*requested)
|
||||
if !canManagePortalUser(r, targetPortalID) {
|
||||
writeError(w, http.StatusForbidden, "Нет прав на просмотр объектов этого сотрудника")
|
||||
return nil, false
|
||||
}
|
||||
owner, err := s.App.EmployeeByPortalUserID(r.Context(), targetPortalID)
|
||||
if errors.Is(err, ErrNotFound) || errors.Is(err, sql.ErrNoRows) {
|
||||
writeError(w, http.StatusNotFound, "employee not found")
|
||||
return nil, false
|
||||
}
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return nil, false
|
||||
}
|
||||
return owner, true
|
||||
}
|
||||
|
||||
func (s Server) projectOwnerIDForAccess(w http.ResponseWriter, r *http.Request, projectID int64) (int64, bool) {
|
||||
owner, err := s.App.ProjectOwner(r.Context(), projectID)
|
||||
if errors.Is(err, ErrNotFound) {
|
||||
@@ -511,6 +549,14 @@ func subordinatePortalIDs(r *http.Request) []string {
|
||||
return out
|
||||
}
|
||||
|
||||
func ownerPortalIDFromQuery(r *http.Request) *string {
|
||||
value := strings.TrimSpace(r.URL.Query().Get("owner_portal_user_id"))
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
return &value
|
||||
}
|
||||
|
||||
func nullablePlain(value string) *string {
|
||||
if strings.TrimSpace(value) == "" {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user