diff --git a/internal/app/club.go b/internal/app/club.go index 36ff85c..c40a398 100644 --- a/internal/app/club.go +++ b/internal/app/club.go @@ -337,3 +337,78 @@ func (s *ClubService) GetClearancePost(ctx context.Context, resp *responses.Chec } return &responses.GetClearance{Access: false, Comment: "only admins"}, nil } + +func (s *ClubService) GetClearanceUpdate(ctx context.Context, req *responses.CheckResponse, clubID int) (*responses.GetClearance, error) { + if req.IsAdmin { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } else { + clubOrgs, err := s.storage.GetClubOrgs(ctx, clubID) + if err != nil { + return &responses.GetClearance{Access: false, Comment: "error"}, fmt.Errorf("can't storage.GetClubOrgs: %w", err) + } + for _, org := range clubOrgs { + if org.ID == req.MemberID { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } + } + } + return &responses.GetClearance{Access: false, Comment: "only admins or club orgs"}, nil +} + +func (s *ClubService) GetClearanceDelete(ctx context.Context, resp *responses.CheckResponse) (*responses.GetClearance, error) { + if resp.IsAdmin { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } + return &responses.GetClearance{Access: false, Comment: "only admins"}, nil +} + +func (s *ClubService) GetClearanceMediaPost(ctx context.Context, req *responses.CheckResponse, clubID int) (*responses.GetClearance, error) { + if req.IsAdmin { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } else { + clubOrgs, err := s.storage.GetClubOrgs(ctx, clubID) + if err != nil { + return &responses.GetClearance{Access: false, Comment: "error"}, fmt.Errorf("can't storage.GetClubOrgs: %w", err) + } + for _, org := range clubOrgs { + if org.ID == req.MemberID { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } + } + } + return &responses.GetClearance{Access: false, Comment: "only admins or club orgs"}, nil +} + +func (s *ClubService) GetClearanceMediaUpdate(ctx context.Context, req *responses.CheckResponse, clubID int) (*responses.GetClearance, error) { + if req.IsAdmin { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } else { + clubOrgs, err := s.storage.GetClubOrgs(ctx, clubID) + if err != nil { + return &responses.GetClearance{Access: false, Comment: "error"}, fmt.Errorf("can't storage.GetClubOrgs: %w", err) + } + for _, org := range clubOrgs { + if org.ID == req.MemberID { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } + } + } + return &responses.GetClearance{Access: false, Comment: "only admins or club orgs"}, nil +} + +func (s *ClubService) GetClearanceMediaDelete(ctx context.Context, req *responses.CheckResponse, clubID int) (*responses.GetClearance, error) { + if req.IsAdmin { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } else { + clubOrgs, err := s.storage.GetClubOrgs(ctx, clubID) + if err != nil { + return &responses.GetClearance{Access: false, Comment: "error"}, fmt.Errorf("can't storage.GetClubOrgs: %w", err) + } + for _, org := range clubOrgs { + if org.ID == req.MemberID { + return &responses.GetClearance{Access: true, Comment: ""}, nil + } + } + } + return &responses.GetClearance{Access: false, Comment: "only admins or club orgs"}, nil +} diff --git a/internal/domain/requests/get-clearance-club-update.go b/internal/domain/requests/get-clearance-club-update.go new file mode 100644 index 0000000..67836ae --- /dev/null +++ b/internal/domain/requests/get-clearance-club-update.go @@ -0,0 +1,28 @@ +package requests + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/go-chi/chi" +) + +type GetClearanceClubUpdate struct { + ClubID int `json:"club_id"` +} + +func (p *GetClearanceClubUpdate) Bind(req *http.Request) error { + id, err := strconv.Atoi(chi.URLParam(req, "club_id")) + if err != nil { + return fmt.Errorf("can't Atoi id on DeleteMember.Bind: %w", err) + } + + p.ClubID = id + + return p.validate() +} + +func (p *GetClearanceClubUpdate) validate() error { + return nil +} diff --git a/internal/ports/clubs.go b/internal/ports/clubs.go index 2900dee..aa4f5de 100644 --- a/internal/ports/clubs.go +++ b/internal/ports/clubs.go @@ -50,12 +50,17 @@ func (h *ClubsHandler) Routes() chi.Router { r.Delete("/media/{club_id}", h.r.Wrap(h.DeleteClubMedia)) r.Put("/media/{club_id}", h.r.Wrap(h.UpdateClubMedia)) r.Get("/clearance/post/", h.r.Wrap(h.GetClearancePost)) + r.Get("/clearance/delete/{club_id}", h.r.Wrap(h.GetClearanceDelete)) + r.Get("/clearance/update/{club_id}", h.r.Wrap(h.GetClearanceUpdate)) + r.Get("/media/clearance/post/{club_id}", h.r.Wrap(h.GetMediaClearancePost)) + r.Get("/media/clearance/delete/{club_id}", h.r.Wrap(h.GetMediaClearanceDelete)) + r.Get("/media/clearance/update/{club_id}", h.r.Wrap(h.GetMediaClearanceUpdate)) return r } func (h *ClubsHandler) GetClearancePost(w http.ResponseWriter, req *http.Request) handler.Response { - h.logger.Info("ClubsHandler: got PostClub request") + h.logger.Info("ClubsHandler: got GetClearancePost request") access, err := getAccessToken(req) if err != nil { @@ -73,7 +78,165 @@ func (h *ClubsHandler) GetClearancePost(w http.ResponseWriter, req *http.Request response, err := h.clubs.GetClearancePost(context.Background(), resp) if err != nil { - h.logger.Warnf("can't clubs.GetClearancePost GetClearancePost: %v", err) + h.logger.Warnf("can't clubs.GetClearancePost: %v", err) + return handler.InternalServerErrorResponse() + } + + return handler.OkResponse(response) +} + +func (h *ClubsHandler) GetClearanceDelete(w http.ResponseWriter, req *http.Request) handler.Response { + h.logger.Info("ClubsHandler: got GetClearanceDelete request") + + access, err := getAccessToken(req) + if err != nil { + h.logger.Warnf("can't get access token: %v", err) + return handler.UnauthorizedResponse() + } + + resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access}) + if err != nil || !resp.Valid { + h.logger.Warnf("Unauthorized request: %v", err) + return handler.UnauthorizedResponse() + } + + h.logger.Infof("ClubsHandler: GetClearanceDelete Authenticated: %v", resp.MemberID) + + response, err := h.clubs.GetClearanceDelete(context.Background(), resp) + if err != nil { + h.logger.Warnf("can't clubs.GetClearanceDelete: %v", err) + return handler.InternalServerErrorResponse() + } + + return handler.OkResponse(response) +} + +func (h *ClubsHandler) GetClearanceUpdate(w http.ResponseWriter, req *http.Request) handler.Response { + h.logger.Info("ClubsHandler: got GetClearanceUpdate request") + + access, err := getAccessToken(req) + if err != nil { + h.logger.Warnf("can't get access token: %v", err) + return handler.UnauthorizedResponse() + } + + resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access}) + if err != nil || !resp.Valid { + h.logger.Warnf("Unauthorized request: %v", err) + return handler.UnauthorizedResponse() + } + + h.logger.Infof("ClubsHandler: GetClearanceUpdate Authenticated: %v", resp.MemberID) + + parsed_req := &requests.GetClearanceClubUpdate{} + err = parsed_req.Bind(req) + if err != nil { + h.logger.Warnf("can't parse request: %v", err) + return handler.BadRequestResponse() + } + + response, err := h.clubs.GetClearanceUpdate(context.Background(), resp, parsed_req.ClubID) + if err != nil { + h.logger.Warnf("can't clubs.GetClearanceUpdate: %v", err) + return handler.InternalServerErrorResponse() + } + + return handler.OkResponse(response) +} + +func (h *ClubsHandler) GetMediaClearancePost(w http.ResponseWriter, req *http.Request) handler.Response { + h.logger.Info("ClubsHandler: got GetMediaClearancePost request") + + access, err := getAccessToken(req) + if err != nil { + h.logger.Warnf("can't get access token: %v", err) + return handler.UnauthorizedResponse() + } + + resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access}) + if err != nil || !resp.Valid { + h.logger.Warnf("Unauthorized request: %v", err) + return handler.UnauthorizedResponse() + } + + h.logger.Infof("ClubsHandler: GetMediaClearancePost Authenticated: %v", resp.MemberID) + + parsed_req := &requests.GetClearanceClubUpdate{} + err = parsed_req.Bind(req) + if err != nil { + h.logger.Warnf("can't parse request: %v", err) + return handler.BadRequestResponse() + } + + response, err := h.clubs.GetClearanceMediaPost(context.Background(), resp, parsed_req.ClubID) + if err != nil { + h.logger.Warnf("can't clubs.GetMediaClearancePost: %v", err) + return handler.InternalServerErrorResponse() + } + + return handler.OkResponse(response) +} + +func (h *ClubsHandler) GetMediaClearanceDelete(w http.ResponseWriter, req *http.Request) handler.Response { + h.logger.Info("ClubsHandler: got GetMediaClearanceDelete request") + + access, err := getAccessToken(req) + if err != nil { + h.logger.Warnf("can't get access token: %v", err) + return handler.UnauthorizedResponse() + } + + resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access}) + if err != nil || !resp.Valid { + h.logger.Warnf("Unauthorized request: %v", err) + return handler.UnauthorizedResponse() + } + + h.logger.Infof("ClubsHandler: GetMediaClearanceDelete Authenticated: %v", resp.MemberID) + + parsed_req := &requests.GetClearanceClubUpdate{} + err = parsed_req.Bind(req) + if err != nil { + h.logger.Warnf("can't parse request: %v", err) + return handler.BadRequestResponse() + } + + response, err := h.clubs.GetClearanceMediaDelete(context.Background(), resp, parsed_req.ClubID) + if err != nil { + h.logger.Warnf("can't clubs.GetMediaClearanceDelete: %v", err) + return handler.InternalServerErrorResponse() + } + + return handler.OkResponse(response) +} + +func (h *ClubsHandler) GetMediaClearanceUpdate(w http.ResponseWriter, req *http.Request) handler.Response { + h.logger.Info("ClubsHandler: got GetMediaClearanceUpdate request") + + access, err := getAccessToken(req) + if err != nil { + h.logger.Warnf("can't get access token: %v", err) + return handler.UnauthorizedResponse() + } + + resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access}) + if err != nil || !resp.Valid { + h.logger.Warnf("Unauthorized request: %v", err) + return handler.UnauthorizedResponse() + } + + h.logger.Infof("ClubsHandler: GetMediaClearanceUpdate Authenticated: %v", resp.MemberID) + + parsed_req := &requests.GetClearanceClubUpdate{} + err = parsed_req.Bind(req) + if err != nil { + h.logger.Warnf("can't parse request: %v", err) + return handler.BadRequestResponse() + } + + response, err := h.clubs.GetClearanceMediaUpdate(context.Background(), resp, parsed_req.ClubID) + if err != nil { + h.logger.Warnf("can't clubs.GetMediaClearanceUpdate: %v", err) return handler.InternalServerErrorResponse() } @@ -323,6 +486,7 @@ func (h *ClubsHandler) GetClubMedia(w http.ResponseWriter, req *http.Request) ha // @Success 200 // @Failure 400 // @Failure 401 +// @Failure 403 // @Failure 409 // @Failure 500 // @Router /clubs [post] @@ -353,6 +517,16 @@ func (h *ClubsHandler) PostClub(w http.ResponseWriter, req *http.Request) handle h.logger.Infof("ClubsHandler: parse request: %v", club) + permission, err := h.clubs.GetClearancePost(context.Background(), resp) + if err != nil { + h.logger.Warnf("can't service.GetClearancePost %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for PostClub: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.PostClub(context.Background(), club) if err != nil { @@ -411,6 +585,16 @@ func (h *ClubsHandler) DeleteClub(w http.ResponseWriter, req *http.Request) hand h.logger.Infof("ClubsHandler: Parsed request: %v", club) + permission, err := h.clubs.GetClearanceDelete(context.Background(), resp) + if err != nil { + h.logger.Warnf("can't service.GetClearanceDelete %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for DeleteClub: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.DeleteClub(context.Background(), club.ID) if err != nil { h.logger.Warnf("can't service.DeleteClub DeleteClub: %v", err) @@ -470,6 +654,16 @@ func (h *ClubsHandler) UpdateClub(w http.ResponseWriter, req *http.Request) hand h.logger.Infof("ClubsHandler: Parsed request: %v", club) + permission, err := h.clubs.GetClearanceUpdate(context.Background(), resp, club.ID) + if err != nil { + h.logger.Warnf("can't service.GetClearanceUpdate %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for UpdateClub: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.UpdateClub(context.Background(), club) if err != nil { h.logger.Warnf("can't service.UpdateClub UpdateClub: %v", err) @@ -530,6 +724,16 @@ func (h *ClubsHandler) PostClubMedia(w http.ResponseWriter, req *http.Request) h h.logger.Infof("ClubsHandler: parse request.") + permission, err := h.clubs.GetClearanceMediaPost(context.Background(), resp, photo.ClubID) + if err != nil { + h.logger.Warnf("can't service.GetClearanceMediaPost %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for PostClubMedia: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.PostClubPhoto(context.Background(), photo) if err != nil { h.logger.Warnf("can't service.PostClubMedia %v", err) @@ -584,6 +788,16 @@ func (h *ClubsHandler) DeleteClubMedia(w http.ResponseWriter, req *http.Request) } h.logger.Infof("ClubsHandler: parse request.") + permission, err := h.clubs.GetClearanceMediaDelete(context.Background(), resp, photo.ClubID) + if err != nil { + h.logger.Warnf("can't service.GetClearanceMediaDelete %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for DeleteClubMedia: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.DeleteClubPhoto(context.Background(), photo) if err != nil { h.logger.Warnf("can't service.DeleteClubMedia %v", err) @@ -640,6 +854,16 @@ func (h *ClubsHandler) UpdateClubMedia(w http.ResponseWriter, req *http.Request) } h.logger.Infof("ClubsHandler: parse request.") + permission, err := h.clubs.GetClearanceMediaUpdate(context.Background(), resp, photo.ClubID) + if err != nil { + h.logger.Warnf("can't service.GetClearanceMediaUpdate %v", err) + return handler.InternalServerErrorResponse() + } + if !permission.Access { + h.logger.Warnf("do not have enough access for UpdateClubMedia: %v", permission.Comment) + return handler.ForbiddenResponse() + } + err = h.clubs.UpdateClubPhoto(context.Background(), photo) if err != nil { h.logger.Warnf("can't service.UpdateClubMedia %v", err) diff --git a/migrations/entrypoint.sh b/migrations/entrypoint.sh index ed0d02b..cd0fbc2 100644 --- a/migrations/entrypoint.sh +++ b/migrations/entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/bash sleep 5 -goose postgres "host=$DB_HOST user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME" reset +# goose postgres "host=$DB_HOST user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME" down goose postgres "host=$DB_HOST user=$DB_USER password=$DB_PASSWORD dbname=$DB_NAME" up \ No newline at end of file