mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-06-08 07:33:52 +02:00
3b322e44e0
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
176 lines
4.2 KiB
Go
176 lines
4.2 KiB
Go
package controller
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/phishingclub/phishingclub/data"
|
|
"github.com/phishingclub/phishingclub/model"
|
|
"github.com/phishingclub/phishingclub/remotebrowser"
|
|
"github.com/phishingclub/phishingclub/repository"
|
|
"github.com/phishingclub/phishingclub/service"
|
|
)
|
|
|
|
// ReportTemplate is the report template controller
|
|
type ReportTemplate struct {
|
|
Common
|
|
ReportTemplateService *service.ReportTemplate
|
|
CampaignService *service.Campaign
|
|
OptionService *service.Option
|
|
ExecPath string
|
|
}
|
|
|
|
// Create creates a report template
|
|
func (r *ReportTemplate) Create(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req model.ReportTemplate
|
|
if ok := r.handleParseRequest(g, &req); !ok {
|
|
return
|
|
}
|
|
id, err := r.ReportTemplateService.Create(g.Request.Context(), session, &req)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
r.Response.OK(g, gin.H{"id": id.String()})
|
|
}
|
|
|
|
// GetAll gets report templates
|
|
func (r *ReportTemplate) GetAll(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
queryArgs, ok := r.handleQueryArgs(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
queryArgs.DefaultSortByUpdatedAt()
|
|
companyID := companyIDFromRequestQuery(g)
|
|
result, err := r.ReportTemplateService.GetAll(
|
|
g.Request.Context(),
|
|
session,
|
|
companyID,
|
|
&repository.ReportTemplateOption{QueryArgs: queryArgs},
|
|
)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
r.Response.OK(g, result)
|
|
}
|
|
|
|
// GetByID gets a report template by id
|
|
func (r *ReportTemplate) GetByID(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := r.handleParseIDParam(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
tmpl, err := r.ReportTemplateService.GetByID(g.Request.Context(), session, id)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
r.Response.OK(g, tmpl)
|
|
}
|
|
|
|
// UpdateByID updates a report template
|
|
func (r *ReportTemplate) UpdateByID(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := r.handleParseIDParam(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req model.ReportTemplate
|
|
if ok := r.handleParseRequest(g, &req); !ok {
|
|
return
|
|
}
|
|
err := r.ReportTemplateService.UpdateByID(g.Request.Context(), session, id, &req)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
r.Response.OK(g, gin.H{})
|
|
}
|
|
|
|
// DeleteByID deletes a report template
|
|
func (r *ReportTemplate) DeleteByID(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := r.handleParseIDParam(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
err := r.ReportTemplateService.DeleteByID(g.Request.Context(), session, id)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
r.Response.OK(g, gin.H{})
|
|
}
|
|
|
|
// GeneratePDFByCampaignID generates a PDF report for a campaign
|
|
func (r *ReportTemplate) GeneratePDFByCampaignID(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
opt, _ := r.OptionService.GetOptionWithoutAuth(g.Request.Context(), data.OptionKeyReportPDFEnabled)
|
|
if opt == nil || opt.Value.String() != "true" {
|
|
r.Response.NotFound(g)
|
|
return
|
|
}
|
|
id, ok := r.handleParseIDParam(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
htmlContent, campaignName, err := r.CampaignService.BuildReportHTML(
|
|
g.Request.Context(),
|
|
session,
|
|
id,
|
|
)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
pdfBytes, err := remotebrowser.RenderHTMLToPDF(g.Request.Context(), htmlContent, r.ExecPath)
|
|
if ok := r.handleErrors(g, err); !ok {
|
|
return
|
|
}
|
|
filename := fmt.Sprintf("report-%s.pdf", sanitizeFilename(campaignName))
|
|
r.responseWithPDF(g, pdfBytes, filename)
|
|
}
|
|
|
|
// WipeBrowserCache deletes the auto-downloaded Chromium binary used for PDF generation.
|
|
func (r *ReportTemplate) WipeBrowserCache(g *gin.Context) {
|
|
session, _, ok := r.handleSession(g)
|
|
if !ok {
|
|
return
|
|
}
|
|
if err := r.ReportTemplateService.WipeBrowserCache(session); err != nil {
|
|
r.handleErrors(g, err)
|
|
return
|
|
}
|
|
r.Response.OK(g, gin.H{})
|
|
}
|
|
|
|
// sanitizeFilename removes characters that are unsafe in filenames
|
|
func sanitizeFilename(name string) string {
|
|
replacer := strings.NewReplacer(
|
|
"/", "-", "\\", "-", ":", "-", "*", "-",
|
|
"?", "-", "\"", "-", "<", "-", ">", "-", "|", "-",
|
|
)
|
|
safe := strings.TrimSpace(replacer.Replace(name))
|
|
if safe == "" {
|
|
return "campaign"
|
|
}
|
|
return safe
|
|
}
|