From 61c787e2c218e72147ece1b31208edeee6c7378b Mon Sep 17 00:00:00 2001 From: Impervguin Date: Wed, 17 Jul 2024 16:48:28 +0300 Subject: [PATCH 1/3] started clearance handlers --- internal/ports/clubs.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/internal/ports/clubs.go b/internal/ports/clubs.go index 2900dee..92820ad 100644 --- a/internal/ports/clubs.go +++ b/internal/ports/clubs.go @@ -50,6 +50,11 @@ 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.Put("/media/clearance/update/{club_id}", h.r.Wrap(h.GetMediaClearanceUpdate)) return r } @@ -80,6 +85,26 @@ func (h *ClubsHandler) GetClearancePost(w http.ResponseWriter, req *http.Request return handler.OkResponse(response) } +func (h *ClubsHandler) GetClearanceDelete(w http.ResponseWriter, req *http.Request) handler.Response { + return handler.OkResponse(nil) +} + +func (h *ClubsHandler) GetClearanceUpdate(w http.ResponseWriter, req *http.Request) handler.Response { + return handler.OkResponse(nil) +} + +func (h *ClubsHandler) GetMediaClearancePost(w http.ResponseWriter, req *http.Request) handler.Response { + return handler.OkResponse(nil) +} + +func (h *ClubsHandler) GetMediaClearanceDelete(w http.ResponseWriter, req *http.Request) handler.Response { + return handler.OkResponse(nil) +} + +func (h *ClubsHandler) GetMediaClearanceUpdate(w http.ResponseWriter, req *http.Request) handler.Response { + return handler.OkResponse(nil) +} + // GetAllClubs // // @Summary Возвращает все клубы из БД From e76867c03d70b36cea335f545c38510c0ee9ec61 Mon Sep 17 00:00:00 2001 From: Impervguin Date: Thu, 5 Sep 2024 20:45:36 +0300 Subject: [PATCH 2/3] Done handlers for club clearance --- internal/app/club.go | 75 +++++++++ .../requests/get-clearance-club-update.go | 28 ++++ internal/ports/clubs.go | 154 +++++++++++++++++- migrations/entrypoint.sh | 2 +- 4 files changed, 250 insertions(+), 9 deletions(-) create mode 100644 internal/domain/requests/get-clearance-club-update.go 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 92820ad..aedbcae 100644 --- a/internal/ports/clubs.go +++ b/internal/ports/clubs.go @@ -54,13 +54,13 @@ func (h *ClubsHandler) Routes() chi.Router { 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.Put("/media/clearance/update/{club_id}", h.r.Wrap(h.GetMediaClearanceUpdate)) + 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 { @@ -78,7 +78,7 @@ 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() } @@ -86,23 +86,161 @@ func (h *ClubsHandler) GetClearancePost(w http.ResponseWriter, req *http.Request } func (h *ClubsHandler) GetClearanceDelete(w http.ResponseWriter, req *http.Request) handler.Response { - return handler.OkResponse(nil) + 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 { - return handler.OkResponse(nil) + 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 { - return handler.OkResponse(nil) + 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 { - return handler.OkResponse(nil) + 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 { - return handler.OkResponse(nil) + 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() + } + + return handler.OkResponse(response) } // GetAllClubs 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 From bf1c88808ca02c86d30d75dbd85b6f1b07271c14 Mon Sep 17 00:00:00 2001 From: Impervguin Date: Thu, 5 Sep 2024 21:32:58 +0300 Subject: [PATCH 3/3] Added club clearance check to club handlers --- internal/ports/clubs.go | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/internal/ports/clubs.go b/internal/ports/clubs.go index aedbcae..aa4f5de 100644 --- a/internal/ports/clubs.go +++ b/internal/ports/clubs.go @@ -486,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] @@ -516,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 { @@ -574,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) @@ -633,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) @@ -693,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) @@ -747,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) @@ -803,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)