diff --git a/.env.template b/.env.template index 8132258..eaa4c07 100644 --- a/.env.template +++ b/.env.template @@ -6,7 +6,12 @@ IMG_MAX_FILE_SIZE_MB=1 IMG_CROP_WIDTH=500 IMG_CROP_HEIGHT=500 -REG_CHECKIN_START=2024-07-21T07:00:00Z +REG_RPKM_CONFIRM_START=2024-07-25T00:00:00Z +REG_RPKM_DAY_ONE_START=2024-08-03T06:00:00Z +REG_RPKM_DAY_TWO_START=2024-08-04T06:00:00Z +REG_FRESHY_NIGHT_CONFIRM_START=2024-08-03T08:00:00Z +REG_FRESHY_NIGHT_CONFIRM_END=2024-08-04T16:00:00Z +REG_FRESHY_NIGHT_START=2024-08-04T16:30:00Z REG_RPKM_START=2024-07-20T20:00:00Z REG_RPKM_END=2024-07-25T00:00:00Z diff --git a/cmd/main.go b/cmd/main.go index ebdf8b7..70916bc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -127,7 +127,7 @@ func main() { checkinClient := checkinProto.NewCheckInServiceClient(checkinConn) checkinSvc := checkin.NewService(checkinClient, logger, tracer) - checkinHdr := checkin.NewHandler(checkinSvc, userSvc, &conf.Reg, validate, logger) + checkinHdr := checkin.NewHandler(checkinSvc, userSvc, &conf.Reg, constant.StaffOnlyCheckin, validate, logger) requestCounter := prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "api_requests_total", diff --git a/config/config.go b/config/config.go index c1330d8..525a38b 100644 --- a/config/config.go +++ b/config/config.go @@ -22,9 +22,14 @@ type ImageConfig struct { } type RegConfig struct { - CheckinStart time.Time - RpkmStart time.Time - RpkmEnd time.Time + RpkmConfirmStart time.Time + RpkmDayOneStart time.Time + RpkmDayTwoStart time.Time + FreshyNightConfirmStart time.Time + FreshyNightConfirmEnd time.Time + FreshyNightStart time.Time + RpkmStart time.Time + RpkmEnd time.Time } type ServiceConfig struct { @@ -88,11 +93,41 @@ func LoadConfig() (*Config, error) { CropHeight: int(cropHeight), } - parsedCheckinTime, err := parseLocalTime("REG_CHECKIN_START") + parsedRpkmConfirmStart, err := parseLocalTime("REG_RPKM_CONFIRM_START") if err != nil { return nil, err } - fmt.Printf("Parsed Checkin start time: %v\n", parsedCheckinTime) + fmt.Printf("Parsed RPKM confirm start time: %v\n", parsedRpkmConfirmStart) + + parsedRpkmDayOneStart, err := parseLocalTime("REG_RPKM_DAY_ONE_START") + if err != nil { + return nil, err + } + fmt.Printf("Parsed RPKM day one start time: %v\n", parsedRpkmDayOneStart) + + parsedRpkmDayTwoStart, err := parseLocalTime("REG_RPKM_DAY_TWO_START") + if err != nil { + return nil, err + } + fmt.Printf("Parsed RPKM day two start time: %v\n", parsedRpkmDayTwoStart) + + parsedFreshyNightConfirmStart, err := parseLocalTime("REG_FRESHY_NIGHT_CONFIRM_START") + if err != nil { + return nil, err + } + fmt.Printf("Parsed Freshy Night confirm start time: %v\n", parsedFreshyNightConfirmStart) + + parsedFreshyNightConfirmEnd, err := parseLocalTime("REG_FRESHY_NIGHT_CONFIRM_END") + if err != nil { + return nil, err + } + fmt.Printf("Parsed Freshy Night confirm end time: %v\n", parsedFreshyNightConfirmEnd) + + parsedFreshyNightStart, err := parseLocalTime("REG_FRESHY_NIGHT_START") + if err != nil { + return nil, err + } + fmt.Printf("Parsed Freshy Night start time: %v\n", parsedFreshyNightStart) parsedRpkmStartTime, err := parseLocalTime("REG_RPKM_START") if err != nil { @@ -107,9 +142,14 @@ func LoadConfig() (*Config, error) { fmt.Printf("Parsed RPKM end time: %v\n", parsedRpkmEndTime) regConfig := RegConfig{ - CheckinStart: parsedCheckinTime, - RpkmStart: parsedRpkmStartTime, - RpkmEnd: parsedRpkmEndTime, + RpkmConfirmStart: parsedRpkmConfirmStart, + RpkmDayOneStart: parsedRpkmDayOneStart, + RpkmDayTwoStart: parsedRpkmDayTwoStart, + FreshyNightConfirmStart: parsedFreshyNightConfirmStart, + FreshyNightConfirmEnd: parsedFreshyNightConfirmEnd, + FreshyNightStart: parsedFreshyNightStart, + RpkmStart: parsedRpkmStartTime, + RpkmEnd: parsedRpkmEndTime, } serviceConfig := ServiceConfig{ diff --git a/constant/checkin.constant.go b/constant/checkin.constant.go new file mode 100644 index 0000000..c93e8ab --- /dev/null +++ b/constant/checkin.constant.go @@ -0,0 +1,13 @@ +package constant + +const RPKM_CONFIRM = "rpkm-confirm" +const RPKM_DAY_ONE = "rpkm-day-1" +const RPKM_DAY_TWO = "rpkm-day-2" +const FRESHY_NIGHT_CONFIRM = "freshy-night-confirm" +const FRESHY_NIGHT = "freshy-night" + +var StaffOnlyCheckin = map[string]struct{}{ + RPKM_DAY_ONE: {}, + RPKM_DAY_TWO: {}, + FRESHY_NIGHT: {}, +} diff --git a/docker-compose.qa.template.yml b/docker-compose.qa.template.yml index e8dc044..c58368e 100644 --- a/docker-compose.qa.template.yml +++ b/docker-compose.qa.template.yml @@ -23,7 +23,12 @@ services: IMG_MAX_FILE_SIZE_MB: 1 IMG_CROP_WIDTH: 500 IMG_CROP_HEIGHT: 500 - REG_CHECKIN_START: "2024-07-21T07:00:00Z" + REG_RPKM_CONFIRM_START: "2024-07-25T00:00:00Z" + REG_RPKM_DAY_ONE_START: "2024-08-03T06:00:00Z" + REG_RPKM_DAY_TWO_START: "2024-08-04T06:00:00Z" + REG_FRESHY_NIGHT_CONFIRM_START: "2024-08-03T08:00:00Z" + REG_FRESHY_NIGHT_CONFIRM_END: "2024-08-04T16:00:00Z" + REG_FRESHY_NIGHT_START: "2024-08-04T16:30:00Z" REG_RPKM_START: "2024-07-20T20:00:00Z" REG_RPKM_END: "2024-07-25T00:00:00Z" SERVICE_AUTH: auth:3002 diff --git a/internal/checkin/checkin.handler.go b/internal/checkin/checkin.handler.go index 3cfe5aa..76b2d71 100644 --- a/internal/checkin/checkin.handler.go +++ b/internal/checkin/checkin.handler.go @@ -1,12 +1,14 @@ package checkin import ( + "fmt" "net/http" "strings" "time" "github.com/isd-sgcu/rpkm67-gateway/apperror" "github.com/isd-sgcu/rpkm67-gateway/config" + "github.com/isd-sgcu/rpkm67-gateway/constant" "github.com/isd-sgcu/rpkm67-gateway/internal/context" "github.com/isd-sgcu/rpkm67-gateway/internal/dto" "github.com/isd-sgcu/rpkm67-gateway/internal/user" @@ -21,20 +23,22 @@ type Handler interface { } type handlerImpl struct { - svc Service - userSvc user.Service - regConf *config.RegConfig - validate validator.DtoValidator - log *zap.Logger + svc Service + userSvc user.Service + regConf *config.RegConfig + staffOnlyCheckin map[string]struct{} + validate validator.DtoValidator + log *zap.Logger } -func NewHandler(svc Service, userSvc user.Service, regConf *config.RegConfig, validate validator.DtoValidator, log *zap.Logger) Handler { +func NewHandler(svc Service, userSvc user.Service, regConf *config.RegConfig, staffOnlyCheckin map[string]struct{}, validate validator.DtoValidator, log *zap.Logger) Handler { return &handlerImpl{ - svc: svc, - userSvc: userSvc, - regConf: regConf, - validate: validate, - log: log, + svc: svc, + userSvc: userSvc, + regConf: regConf, + staffOnlyCheckin: staffOnlyCheckin, + validate: validate, + log: log, } } @@ -50,16 +54,6 @@ func NewHandler(svc Service, userSvc user.Service, regConf *config.RegConfig, va // @Failure 400 {object} apperror.AppError // @Router /checkin [post] func (h *handlerImpl) Create(c context.Ctx) { - if !h.checkRegTime() { - c.ForbiddenError("Registration hasn't started") - return - } - - // if c.GetString("role") != "staff" { - // c.ResponseError(apperror.ForbiddenError("only staff can access this endpoint")) - // return - // } - tr := c.GetTracer() ctx, span := tr.Start(c.RequestContext(), "handler.checkin.Create") defer span.End() @@ -71,6 +65,18 @@ func (h *handlerImpl) Create(c context.Ctx) { return } + _, isStaffOnlyCheckin := h.staffOnlyCheckin[body.Event] + if c.GetString("role") != "staff" && isStaffOnlyCheckin { + c.ResponseError(apperror.ForbiddenError(fmt.Sprintf("only staff can create checkin for event %s", body.Event))) + return + } + + ok, msg := h.checkRegTime(body.Event) + if !ok { + c.ForbiddenError(msg) + return + } + if errorList := h.validate.Validate(body); errorList != nil { h.log.Named("Create").Error("Validate: ", zap.Strings("errorList", errorList)) c.BadRequestError(strings.Join(errorList, ", ")) @@ -123,16 +129,6 @@ func (h *handlerImpl) Create(c context.Ctx) { // @Failure 400 {object} apperror.AppError // @Router /checkin/email/{email} [get] func (h *handlerImpl) FindByEmail(c context.Ctx) { - if !h.checkRegTime() { - c.ForbiddenError("Registration hasn't started") - return - } - - if c.GetString("role") != "staff" { - c.ResponseError(apperror.ForbiddenError("only staff can access this endpoint")) - return - } - tr := c.GetTracer() ctx, span := tr.Start(c.RequestContext(), "handler.checkin.FindByEmail") defer span.End() @@ -172,16 +168,6 @@ func (h *handlerImpl) FindByEmail(c context.Ctx) { // @Failure 400 {object} apperror.AppError // @Router /checkin/{userId} [get] func (h *handlerImpl) FindByUserID(c context.Ctx) { - if !h.checkRegTime() { - c.ForbiddenError("Registration hasn't started") - return - } - - if c.GetString("role") != "staff" { - c.ResponseError(apperror.ForbiddenError("only staff can access this endpoint")) - return - } - tr := c.GetTracer() ctx, span := tr.Start(c.RequestContext(), "handler.checkin.FindByUserID") defer span.End() @@ -209,14 +195,40 @@ func (h *handlerImpl) FindByUserID(c context.Ctx) { }) } -func (h *handlerImpl) checkRegTime() bool { +func (h *handlerImpl) checkRegTime(event string) (bool, string) { nowUTC := time.Now().UTC() gmtPlus7Location := time.FixedZone("GMT+7", 7*60*60) nowGMTPlus7 := nowUTC.In(gmtPlus7Location) - if nowGMTPlus7.Before(h.regConf.CheckinStart) { - h.log.Named("checkRegTime").Warn("Forbidden: Registration hasn't started") - return false - } - - return true + switch event { + case constant.RPKM_CONFIRM: + if nowGMTPlus7.Before(h.regConf.RpkmConfirmStart) { + h.log.Named("checkRegTime").Warn("Forbidden: RPKM67 Confirmation Registration hasn't started") + return false, "RPKM67 Confirmation Registration hasn't started" + } + case constant.RPKM_DAY_ONE: + if nowGMTPlus7.Before(h.regConf.RpkmDayOneStart) { + h.log.Named("checkRegTime").Warn("Forbidden: RPKM67 Day One Registration hasn't started") + return false, "RPKM67 Day One Registration hasn't started" + } + case constant.RPKM_DAY_TWO: + if nowGMTPlus7.Before(h.regConf.RpkmDayTwoStart) { + h.log.Named("checkRegTime").Warn("Forbidden: RPKM67 Day Two Registration hasn't started") + return false, "RPKM67 Day Two Registration hasn't started" + } + case constant.FRESHY_NIGHT_CONFIRM: + if nowGMTPlus7.Before(h.regConf.FreshyNightConfirmStart) { + h.log.Named("checkRegTime").Warn("Forbidden: Freshy Night Confirmation Registration hasn't started") + return false, "Freshy Night Confirmation Registration hasn't started" + } else if nowGMTPlus7.After(h.regConf.FreshyNightConfirmEnd) { + h.log.Named("checkRegTime").Warn("Forbidden: Freshy Night Confirmation Registration has ended") + return false, "Freshy Night Confirmation Registration has ended" + } + case constant.FRESHY_NIGHT: + if nowGMTPlus7.Before(h.regConf.FreshyNightStart) { + h.log.Named("checkRegTime").Warn("Forbidden: Freshy Night Registration hasn't started") + return false, "Freshy Night Registration hasn't started" + } + } + + return true, "" }