package controller import ( "fmt" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/oapi-codegen/nullable" "github.com/phishingclub/phishingclub/database" "github.com/phishingclub/phishingclub/model" "github.com/phishingclub/phishingclub/repository" "github.com/phishingclub/phishingclub/service" ) // RecipientGroupColumnsMap is a map between the frontend and the backend // so the frontend has user friendly names instead of direct references // to the database schema // this is tied to a slice in the repository package var RecipientGroupColumnsMap = map[string]string{ "created_at": repository.TableColumn(database.RECIPIENT_GROUP_TABLE, "created_at"), "updated_at": repository.TableColumn(database.RECIPIENT_GROUP_TABLE, "updated_at"), "name": repository.TableColumn(database.RECIPIENT_GROUP_TABLE, "name"), } // AddRecipientRequest is a request to add recipients to a recipient group type AddRecipientRequest struct { RecipientIDs []string `json:"recipientIDs"` } // RemoveRecipientRequest is a request to remove recipients from a recipient group type RemoveRecipientRequest struct { RecipientIDs []string `json:"recipientIDs"` } // RecipientGroup is a recipient group controller type RecipientGroup struct { Common RecipientGroupService *service.RecipientGroup } // Create creates a new recipient group func (r *RecipientGroup) Create(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse request var req model.RecipientGroup if ok := r.handleParseRequest(g, &req); !ok { return } // save recipient group recipientGroupID, err := r.RecipientGroupService.Create( g.Request.Context(), session, &req, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK( g, &gin.H{ "id": recipientGroupID.String(), }, ) } // GetAll returns all recipient groups using pagination func (r *RecipientGroup) GetAll(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse request queryArgs, ok := r.handleQueryArgs(g) if !ok { return } queryArgs.DefaultSortByName() queryArgs.RemapOrderBy(RecipientGroupColumnsMap) companyContextID := companyIDFromRequestQuery(g) // get recipient groups recipientGroups, err := r.RecipientGroupService.GetAll( g, session, companyContextID, &repository.RecipientGroupOption{ QueryArgs: queryArgs, WithCompany: true, WithRecipientCount: true, }, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, recipientGroups) } // GetByID gets a recipient group by id func (r *RecipientGroup) GetByID(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse id id, ok := r.handleParseIDParam(g) if !ok { return } recipientGroup, err := r.RecipientGroupService.GetByID( g.Request.Context(), session, id, &repository.RecipientGroupOption{ WithCompany: true, }, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, recipientGroup) } // GetRecipientsByGroupID gets recipients by recipient group id func (r *RecipientGroup) GetRecipientsByGroupID(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse id id, ok := r.handleParseIDParam(g) if !ok { return } queryArgs, ok := r.handleQueryArgs(g) if !ok { return } queryArgs.DefaultSortBy("email") // remap query args queryArgs.RemapOrderBy(recipientColumnByMap) if !ok { return } // get recipients ctx := g.Request.Context() recipients, err := r.RecipientGroupService.GetRecipientsByGroupID( ctx, session, id, &repository.RecipientOption{ QueryArgs: queryArgs, WithCompany: true, }, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, recipients) } // UpdateByID updates a recipient group by id // updates only the name and company relations func (r *RecipientGroup) UpdateByID(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse id id, ok := r.handleParseIDParam(g) if !ok { return } // parse request var req model.RecipientGroup if ok := r.handleParseRequest(g, &req); !ok { return } // check if recipient group exists already exists err := r.RecipientGroupService.UpdateByID( g.Request.Context(), session, id, &req, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, &gin.H{}) } // Import imports recipients to a recipient group func (r *RecipientGroup) Import(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse request groupID, ok := r.handleParseIDParam(g) if !ok { return } var req struct { Recipients []*model.Recipient `json:"recipients"` CompanyID *uuid.UUID `json:"companyID"` IgnoreOverwriteEmptyFields nullable.Nullable[bool] `json:"ignoreOverwriteEmptyFields"` } if ok := r.handleParseRequest(g, &req); !ok { return } // IgnoreOverwriteEmptyFields default value is true if !req.IgnoreOverwriteEmptyFields.IsSpecified() || req.IgnoreOverwriteEmptyFields.IsNull() { req.IgnoreOverwriteEmptyFields = nullable.NewNullableWithValue(true) } result, err := r.RecipientGroupService.Import( g, session, req.Recipients, req.IgnoreOverwriteEmptyFields.MustGet(), groupID, req.CompanyID, ) if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, result) } // AddRecipients adds recipients to a recipient group func (r *RecipientGroup) AddRecipients(g *gin.Context) { // handle session session, _, ok := r.handleSession(g) if !ok { return } // parse group ID groupID, ok := r.handleParseIDParam(g) if !ok { return } // parse request var req AddRecipientRequest if ok := r.handleParseRequest(g, &req); !ok { return } // parse recipient ids recipientIDs := []*uuid.UUID{} for _, id := range req.RecipientIDs { rid, err := uuid.Parse(id) if err != nil { r.Logger.Debugw("failed to add recipients to recipient group", "error", fmt.Errorf("failed to parse recipient id: %w", err), ) r.Response.BadRequestMessage(g, "invalid recipient id") return } recipientIDs = append(recipientIDs, &rid) } // add recipients err := r.RecipientGroupService.AddRecipients( g.Request.Context(), session, groupID, recipientIDs, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, &gin.H{}) } // RemoveRecipients removes a recipient from a recipient group func (r *RecipientGroup) RemoveRecipients(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse id id, ok := r.handleParseIDParam(g) if !ok { return } // parse request var req RemoveRecipientRequest if ok := r.handleParseRequest(g, &req); !ok { return } // parse recipient ids recipientIDs := []*uuid.UUID{} for _, id := range req.RecipientIDs { rid, err := uuid.Parse(id) if err != nil { r.Logger.Debugw("failed to remove recipients from recipient group", "error", fmt.Errorf("failed to parse recipient id: %w", err), ) r.Response.BadRequestMessage(g, "invalid recipient id") return } recipientIDs = append(recipientIDs, &rid) } // remove recipients err := r.RecipientGroupService.RemoveRecipients( g.Request.Context(), session, id, recipientIDs, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK(g, &gin.H{}) } // DeleteByID deletes a recipient group by id // deleting a group also deletes all recipients in that group func (r *RecipientGroup) DeleteByID(g *gin.Context) { session, _, ok := r.handleSession(g) if !ok { return } // parse id id, ok := r.handleParseIDParam(g) if !ok { return } // delete recipient group err := r.RecipientGroupService.DeleteByID( g.Request.Context(), session, id, ) // handle response if ok := r.handleErrors(g, err); !ok { return } r.Response.OK( g, &gin.H{}, ) }