-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6d584c5
commit 79dada7
Showing
11 changed files
with
316 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,16 @@ | ||
DB_NAME=campus_db | ||
DB_ROOT_PASSWORD=secret_root_password | ||
DB_PORT=3306 | ||
|
||
APNS_KEY_ID= | ||
APNS_TEAM_ID= | ||
APNS_P8_FILE_PATH=/secrets/AuthKey_XXXX.p8 | ||
|
||
ENVIRONMENT=dev | ||
|
||
SENTRY_DSN= | ||
|
||
SMTP_PASSWORD= | ||
SMTP_URL= | ||
SMTP_USERNAME= | ||
SMTP_PORT= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,10 @@ services: | |
- APNS_TEAM_ID=${APNS_TEAM_ID} | ||
- APNS_P8_FILE_PATH=${APNS_P8_FILE_PATH} | ||
- MensaCronDisabled=false | ||
- SMTP_PASSWORD=${SMTP_PASSWORD} | ||
- SMTP_URL=${SMTP_URL:-postout.lrz.de} | ||
- SMTP_USERNAME=${SMTP_USERNAME:[email protected]} | ||
- SMTP_PORT=${SMTP_PORT:-587} | ||
volumes: | ||
- backend-storage:/Storage | ||
- ./apns_auth_key.p8:${APNS_P8_FILE_PATH} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<h1>Feedback via TumCampusApp:</h1> | ||
{{ if .Feedback.Valid -}} | ||
<blockquote> | ||
{{- .Feedback.String -}} | ||
</blockquote> | ||
{{- else -}} | ||
<i>no feedback provided</i> | ||
{{- end }} | ||
<table> | ||
<tr> | ||
<th>Inforation type</th> | ||
<th>Details</th> | ||
</tr> | ||
{{- if .Latitude.Valid }} | ||
<tr> | ||
<th>Nutzer-Standort</th> | ||
<td> | ||
<a href="https://www.google.com/maps/search/?api=1&query={{ .Latitude.Float64 }},{{ .Longitude.Float64 }}"> | ||
latitude: {{ .Latitude.Float64 }}, longitude: {{ .Longitude.Float64 }} | ||
</a> | ||
</td> | ||
</tr> | ||
{{- end }} | ||
<tr> | ||
<th>OS-Version</th> | ||
<td>{{ if .OsVersion.Valid }}{{.OsVersion.String }}{{else}}unknown{{end}}</td> | ||
</tr> | ||
<tr> | ||
<th>App-Version</th> | ||
<td>{{ if .AppVersion.Valid }}{{.AppVersion.String }}{{else}}unknown{{end}}</td> | ||
</tr> | ||
</table> | ||
{{- if .ImageCount }} | ||
<h2>Fotos:</h2><br/> | ||
<ol> | ||
{{- range $val := iterate .ImageCount }} | ||
<li> | ||
<a href="https://app.tum.de/File/feedback/{{ $.Id }}/{{ $val }}.png">Foto {{ $val }}</a> | ||
</li> | ||
{{- end }} | ||
</ol> | ||
{{- end -}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Feedback via TumCampusApp: | ||
|
||
{{ if .Feedback.Valid }} | ||
{{- .Feedback.String -}} | ||
{{ else -}} | ||
no feedback provided | ||
{{- end }} | ||
|
||
Metadata: | ||
{{- if .Latitude.Valid }} | ||
- Nutzer-Standort: {{ .Latitude.Float64 }},{{ .Longitude.Float64 }} (latitude,longitude) | ||
https://www.google.com/maps/search/?api=1&query={{ .Latitude.Float64 }},{{ .Longitude.Float64 }} | ||
{{- end }} | ||
- OS-Version: {{ if .OsVersion.Valid }}{{.OsVersion.String }}{{else}}unknown{{end}} | ||
- App-Version: {{ if .AppVersion.Valid }}{{.AppVersion.String }}{{else}}unknown{{end}} | ||
{{- if .ImageCount }} | ||
|
||
Photos: | ||
{{- range $val := iterate .ImageCount }} | ||
- Photo {{ $val }}: https://app.tum.de/File/feedback/{{ $.Id }}/{{ $val }}.png | ||
{{- end -}} | ||
{{- end -}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package cron | ||
|
||
import ( | ||
"bytes" | ||
"crypto/tls" | ||
htmlTemplate "html/template" | ||
"os" | ||
"strconv" | ||
textTemplate "text/template" | ||
"time" | ||
|
||
"github.com/TUM-Dev/Campus-Backend/server/model" | ||
log "github.com/sirupsen/logrus" | ||
"gopkg.in/gomail.v2" | ||
|
||
_ "embed" | ||
) | ||
|
||
// iterate is necessary, as go otherwise cannot count up in a for loop inside templates | ||
func iterate(count int32) []int32 { | ||
var items []int32 | ||
var i int32 | ||
for i = 0; i < count; i++ { | ||
items = append(items, i) | ||
} | ||
return items | ||
} | ||
|
||
//go:embed emailTemplates/feedbackBody.gohtml | ||
var htmlFeedbackBody string | ||
|
||
//go:embed emailTemplates/feedbackBody.txt.tmpl | ||
var txtFeedbackBody string | ||
|
||
func parseTemplates() (*htmlTemplate.Template, *textTemplate.Template, error) { | ||
funcMap := textTemplate.FuncMap{"iterate": iterate} | ||
parsedHtmlBody, err := htmlTemplate.New("htmlFeedbackBody").Funcs(funcMap).Parse(htmlFeedbackBody) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
parsedTxtBody, err := textTemplate.New("txtFeedbackBody").Funcs(funcMap).Parse(txtFeedbackBody) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
return parsedHtmlBody, parsedTxtBody, nil | ||
|
||
} | ||
|
||
type MailHeaders struct { | ||
From string | ||
To string | ||
ReplyTo string //optional | ||
Timestamp time.Time | ||
Subject string | ||
} | ||
|
||
func messageWithHeaders(feedback *model.Feedback) *gomail.Message { | ||
m := gomail.NewMessage() | ||
// From | ||
m.SetAddressHeader("From", os.Getenv("SMTP_USERNAME"), "TUM Campus App") | ||
// To | ||
if feedback.Receiver.Valid { | ||
m.SetHeader("To", feedback.Receiver.String) | ||
} else { | ||
m.SetHeader("To", "[email protected]") | ||
} | ||
// ReplyTo | ||
if feedback.ReplyTo.Valid { | ||
m.SetHeader("Reply-To", feedback.ReplyTo.String) | ||
} | ||
// Timestamp | ||
if feedback.Timestamp.Valid { | ||
m.SetDateHeader("Date", feedback.Timestamp.Time) | ||
} else { | ||
m.SetDateHeader("Date", time.Now()) | ||
} | ||
// Subject | ||
m.SetHeader("Subject", "Feedback via Tum Campus App") | ||
return m | ||
} | ||
|
||
func generateTemplatedMail(parsedHtmlBody *htmlTemplate.Template, parsedTxtBody *textTemplate.Template, feedback *model.Feedback) (string, string, error) { | ||
var htmlBodyBuffer bytes.Buffer | ||
if err := parsedHtmlBody.Execute(&htmlBodyBuffer, feedback); err != nil { | ||
return "", "", err | ||
} | ||
var txtBodyBuffer bytes.Buffer | ||
if err := parsedTxtBody.Execute(&txtBodyBuffer, feedback); err != nil { | ||
return "", "", err | ||
} | ||
return htmlBodyBuffer.String(), txtBodyBuffer.String(), nil | ||
} | ||
|
||
func (c *CronService) feedbackEmailCron() error { | ||
|
||
var results []model.Feedback | ||
if err := c.db.Find(&results, "processed = false").Scan(&results).Error; err != nil { | ||
log.WithError(err).Fatal("could not get unprocessed feedback") | ||
return err | ||
} | ||
parsedHtmlBody, parsedTxtBody, err := parseTemplates() | ||
if err != nil { | ||
log.WithError(err).Fatal("could not parse email templates") | ||
return err | ||
} | ||
|
||
smtpPort, err := strconv.Atoi(os.Getenv("SMTP_PORT")) | ||
if err != nil { | ||
log.WithError(err).Fatal("SMTP_PORT is not an integer") | ||
return err | ||
} | ||
d := gomail.NewDialer(os.Getenv("SMTP_URL"), smtpPort, os.Getenv("SMTP_USERNAME"), os.Getenv("SMTP_PASSWORD")) | ||
d.TLSConfig = &tls.Config{InsecureSkipVerify: true} | ||
for i, feedback := range results { | ||
m := messageWithHeaders(&feedback) | ||
|
||
// attach a body | ||
htmlBodyBuffer, txtBodyBuffer, err := generateTemplatedMail(parsedHtmlBody, parsedTxtBody, &feedback) | ||
if err != nil { | ||
log.WithError(err).Error("Could not template mail body") | ||
return err | ||
} | ||
m.SetBody("text/plain", txtBodyBuffer) | ||
m.AddAlternative("text/html", htmlBodyBuffer) | ||
|
||
// send mail | ||
if err := d.DialAndSend(m); err != nil { | ||
log.WithError(err).Error("could not send mail") | ||
continue | ||
} | ||
log.Tracef("sending feedback %d to %v successfull", i, feedback.Receiver) | ||
|
||
// prevent the message being send the next time around | ||
if err := c.db.Find(model.Feedback{}, "id = ?", feedback.Id).Update("processed", "true").Error; err != nil { | ||
log.WithError(err).Error("could not prevent mail from being send again") | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package migration | ||
|
||
import ( | ||
"database/sql" | ||
|
||
"github.com/TUM-Dev/Campus-Backend/server/model" | ||
"github.com/go-gormigrate/gormigrate/v2" | ||
"github.com/guregu/null" | ||
"gorm.io/gorm" | ||
) | ||
|
||
type Feedback struct { | ||
Processed bool `gorm:"column:processed;type:boolean;default:false;not null;"` | ||
OsVersion sql.NullString `gorm:"column:os_version;type:text;null;"` | ||
AppVersion sql.NullString `gorm:"column:app_version;type:text;null;"` | ||
} | ||
|
||
// TableName sets the insert table name for this struct type | ||
func (n *Feedback) TableName() string { | ||
return "feedback" | ||
} | ||
|
||
// migrate20230826000000 | ||
// adds a "feedbackEmail" cron job that runs every 30 minutes. | ||
func (m TumDBMigrator) migrate20230826000000() *gormigrate.Migration { | ||
return &gormigrate.Migration{ | ||
ID: "20230826000000", | ||
Migrate: func(tx *gorm.DB) error { | ||
if err := tx.Migrator().AddColumn(&Feedback{}, "Processed"); err != nil { | ||
return err | ||
} | ||
if err := tx.Migrator().AddColumn(&Feedback{}, "OsVersion"); err != nil { | ||
return err | ||
} | ||
if err := tx.Migrator().AddColumn(&Feedback{}, "AppVersion"); err != nil { | ||
return err | ||
} | ||
if err := tx.Exec("UPDATE feedback SET processed = true WHERE processed != true;").Error; err != nil { | ||
return err | ||
} | ||
if err := SafeEnumMigrate(tx, &model.Crontab{}, "type", "feedbackEmail"); err != nil { | ||
return err | ||
} | ||
return tx.Create(&model.Crontab{ | ||
Interval: 60 * 30, // Every 30 minutes | ||
Type: null.String{NullString: sql.NullString{String: "feedbackEmail", Valid: true}}, | ||
}).Error | ||
}, | ||
|
||
Rollback: func(tx *gorm.DB) error { | ||
if err := tx.Migrator().DropColumn(&Feedback{}, "Processed"); err != nil { | ||
return err | ||
} | ||
if err := tx.Migrator().DropColumn(&Feedback{}, "OsVersion"); err != nil { | ||
return err | ||
} | ||
if err := tx.Migrator().DropColumn(&Feedback{}, "AppVersion"); err != nil { | ||
return err | ||
} | ||
if err := tx.Delete(&model.Crontab{}, "type = ? AND interval = ?", "fileDownload", 30*60).Error; err != nil { | ||
return err | ||
} | ||
return SafeEnumMigrate(tx, &model.Crontab{}, "type", "feedbackEmail") | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.