Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions database/student.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ func (d *Database) GetStudentByEmail(ctx context.Context, email string) (*Studen
var student Student
var parentEmail, signatory, dietaryRestrictions sql.NullString
err := d.DB.QueryRow(ctx, `
SELECT teamid, email, name, age, parentemail, signatory, ctfdpassword,
SELECT teamid, email, name, age, parentemail, signatory, previouslyparticipated, ctfdpassword,
EmailConfirmed, liabilitywaiver, computerusewaiver, dietaryrestrictions, qrcodesent, checkedin, ctfdpasswordsent
FROM students
WHERE email = $1
`, email).Scan(&student.TeamID, &student.Email, &student.Name, &student.Age,
&parentEmail, &signatory, &student.CTFdPassword, &student.EmailConfirmed,
&parentEmail, &signatory, &student.PreviouslyParticipated, &student.CTFdPassword, &student.EmailConfirmed,
&student.LiabilitySigned, &student.ComputerUseWaiverSigned,
&dietaryRestrictions, &student.QRCodeSent, &student.CheckedIn, &student.CTFdPasswordSent)
if err != nil {
Expand Down
28 changes: 14 additions & 14 deletions database/teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ type TeamWithTeacherName struct {
}

type Student struct {
TeamID uuid.UUID
Email string
Name string
Age int
ParentEmail string
Signatory string
CTFdPassword string
// PreviouslyParticipated bool
TeamID uuid.UUID
Email string
Name string
Age int
ParentEmail string
Signatory string
CTFdPassword string
PreviouslyParticipated bool
LiabilitySigned bool
ComputerUseWaiverSigned bool
EmailConfirmed bool
Expand Down Expand Up @@ -87,7 +87,7 @@ func (d *Database) scanTeamWithTeacherName(row dbutil.Scannable) (*TeamWithTeach

func (d *Database) scanTeamStudents(ctx context.Context, team *Team) error {
studentRows, err := d.DB.Query(ctx, `
SELECT s.email, s.name, s.age, s.parentemail, s.signatory, s.ctfdpassword, s.emailconfirmed, s.liabilitywaiver, s.computerusewaiver, s.dietaryrestrictions, s.qrcodesent, s.checkedin, s.ctfdpasswordsent
SELECT s.email, s.name, s.age, s.parentemail, s.signatory, s.previouslyparticipated, s.ctfdpassword, s.emailconfirmed, s.liabilitywaiver, s.computerusewaiver, s.dietaryrestrictions, s.qrcodesent, s.checkedin, s.ctfdpasswordsent
FROM students s
WHERE s.teamid = ?
`, team.ID)
Expand All @@ -99,7 +99,7 @@ func (d *Database) scanTeamStudents(ctx context.Context, team *Team) error {
var s Student
var parentEmail, signatory, dietaryRestrictions sql.NullString
// var campusTour sql.NullBool
if err := studentRows.Scan(&s.Email, &s.Name, &s.Age, &parentEmail, &signatory, &s.CTFdPassword, &s.EmailConfirmed,
if err := studentRows.Scan(&s.Email, &s.Name, &s.Age, &parentEmail, &signatory, &s.PreviouslyParticipated, &s.CTFdPassword, &s.EmailConfirmed,
&s.LiabilitySigned, &s.ComputerUseWaiverSigned, &dietaryRestrictions, &s.QRCodeSent, &s.CheckedIn, &s.CTFdPasswordSent); err != nil {
return err
}
Expand Down Expand Up @@ -228,15 +228,15 @@ func (d *Database) UpsertTeam(ctx context.Context, teacherEmail string, teamID u
return err
}

func (d *Database) AddTeamMember(ctx context.Context, teamID uuid.UUID, name string, studentAge int, studentEmail string) error {
func (d *Database) AddTeamMember(ctx context.Context, teamID uuid.UUID, name string, studentAge int, studentEmail string, previouslyParticipated bool) error {
CTFdPassword, passerr := password.Generate(12, 2, 2, false, false)
if passerr != nil {
return passerr
}
_, err := d.DB.Exec(ctx, `
INSERT INTO students (teamid, name, age, email, ctfdpassword)
VALUES (?, ?, ?, ?, ?)
`, teamID, name, studentAge, studentEmail, CTFdPassword)
INSERT INTO students (teamid, name, age, email, previouslyparticipated, ctfdpassword)
VALUES (?, ?, ?, ?, ?, ?)
`, teamID, name, studentAge, studentEmail, previouslyParticipated, CTFdPassword)
return err
}

Expand Down
2 changes: 1 addition & 1 deletion database/v01_initial_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ CREATE TABLE IF NOT EXISTS students (
dietaryrestrictions TEXT,
ctfdpassword TEXT NOT NULL,
-- campustour BOOLEAN,
-- previouslyparticipated BOOLEAN NOT NULL DEFAULT FALSE,
previouslyparticipated BOOLEAN NOT NULL DEFAULT FALSE,
emailconfirmed BOOLEAN NOT NULL DEFAULT FALSE,

-- Waivers
Expand Down
170 changes: 46 additions & 124 deletions internal/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func (a *Application) GetAdminTeamsTemplate(r *http.Request) map[string]any {
var beginnerInPersonTeams, advancedInPersonTeams int
var beginnerInPersonStudents, advancedInPersonStudents int
var emailConfirmed, formsSigned int
var checkedIn int
for _, team := range teamsWithTeachers {
teams++
// if team.Division == database.DivisionBeginner {
Expand Down Expand Up @@ -109,6 +110,10 @@ func (a *Application) GetAdminTeamsTemplate(r *http.Request) map[string]any {
if member.LiabilitySigned {
formsSigned++
}

if member.CheckedIn {
checkedIn++
}
}
}

Expand Down Expand Up @@ -147,6 +152,7 @@ func (a *Application) GetAdminTeamsTemplate(r *http.Request) map[string]any {
// "CampusTourStudents": campusTour,
"EmailConfirmedStudents": emailConfirmed,
"FormsSignedStudents": formsSigned,
"CheckedInStudents": checkedIn,
}
}

Expand Down Expand Up @@ -243,18 +249,6 @@ func (a *Application) HandleAdminLogin(w http.ResponseWriter, r *http.Request) {

func (a *Application) HandleResendStudentEmail(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

email := r.URL.Query().Get("email")
if email == "" {
Expand Down Expand Up @@ -300,18 +294,6 @@ func (a *Application) HandleResendStudentEmail(w http.ResponseWriter, r *http.Re

func (a *Application) HandleResendParentEmail(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

email := r.URL.Query().Get("email")
if email == "" {
Expand Down Expand Up @@ -343,27 +325,14 @@ func (a *Application) HandleResendParentEmail(w http.ResponseWriter, r *http.Req

func (a *Application) HandleGetStudentEmailConfirmationLink(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

email := r.URL.Query().Get("email")
if email == "" {
a.Log.Warn().Msg("no email address provided in query string")
w.WriteHeader(http.StatusBadRequest)
return
}

_, err = a.DB.GetStudentByEmail(ctx, email)
_, err := a.DB.GetStudentByEmail(ctx, email)
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get student by email")
w.WriteHeader(http.StatusBadRequest)
Expand All @@ -382,18 +351,6 @@ func (a *Application) HandleGetStudentEmailConfirmationLink(w http.ResponseWrite

func (a *Application) HandleGetParentEmailConfirmationLink(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

email := r.URL.Query().Get("email")
if email == "" {
Expand All @@ -402,7 +359,7 @@ func (a *Application) HandleGetParentEmailConfirmationLink(w http.ResponseWriter
return
}

_, err = a.DB.GetStudentByEmail(ctx, email)
_, err := a.DB.GetStudentByEmail(ctx, email)
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get student by email")
w.WriteHeader(http.StatusBadRequest)
Expand All @@ -422,18 +379,6 @@ func (a *Application) HandleGetParentEmailConfirmationLink(w http.ResponseWriter
func (a *Application) HandleSendEmailConfirmationReminders(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := hlog.FromRequest(r).With().Str("action", "send_email_confirmation_reminders").Logger()
tok, err := r.Cookie("admin_token")
if err != nil {
log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
Expand Down Expand Up @@ -465,19 +410,6 @@ func (a *Application) HandleSendParentReminders(w http.ResponseWriter, r *http.R
ctx := r.Context()
log := hlog.FromRequest(r).With().Str("action", "send_parent_reminders").Logger()

tok, err := r.Cookie("admin_token")
if err != nil {
log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
log.Err(err).Msg("failed to get teams with teachers")
Expand Down Expand Up @@ -511,18 +443,6 @@ func (a *Application) HandleSendParentReminders(w http.ResponseWriter, r *http.R
func (a *Application) HandleSendQRCodes(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := hlog.FromRequest(r).With().Str("action", "send_parent_reminders").Logger()
tok, err := r.Cookie("admin_token")
if err != nil {
log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
Expand Down Expand Up @@ -561,18 +481,6 @@ func (a *Application) HandleSendQRCodes(w http.ResponseWriter, r *http.Request)
func (a *Application) HandleSendCTFdPasswords(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
log := hlog.FromRequest(r).With().Str("action", "send_parent_reminders").Logger()
tok, err := r.Cookie("admin_token")
if err != nil {
log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
Expand Down Expand Up @@ -610,18 +518,6 @@ func (a *Application) HandleSendCTFdPasswords(w http.ResponseWriter, r *http.Req

func (a *Application) HandleCTFdUsersExport(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
Expand Down Expand Up @@ -651,18 +547,6 @@ func (a *Application) HandleCTFdUsersExport(w http.ResponseWriter, r *http.Reque

func (a *Application) HandleCTFdTeamsExport(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tok, err := r.Cookie("admin_token")
if err != nil {
a.Log.Warn().Err(err).Msg("failed to get admin token")
w.WriteHeader(http.StatusBadRequest)
return
}

if isAdmin, err := a.isAdminByToken(tok.Value); err != nil || !isAdmin {
a.Log.Warn().Err(err).Msg("user is not admin!")
w.WriteHeader(http.StatusBadRequest)
return
}

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
Expand All @@ -683,3 +567,41 @@ func (a *Application) HandleCTFdTeamsExport(w http.ResponseWriter, r *http.Reque
}
writer.Flush()
}

func (a *Application) HandleManualCheckin(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

email := r.URL.Query().Get("email")
a.DB.SignFormsForStudent(ctx, email, "SIGNED IN PERSON")
a.DB.CheckInStudent(ctx, email)
http.Redirect(w, r, "/admin/teams", http.StatusSeeOther)
}

func (a *Application) HandleTeamList(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
onlyFirstTime := r.URL.Query().Get("firsttime") == "true"

teamsWithTeachers, err := a.DB.GetAdminTeamsWithTeacherName(ctx)
if err != nil {
a.Log.Err(err).Msg("failed to get teams with teachers")
w.WriteHeader(http.StatusInternalServerError)
return
}

for _, team := range teamsWithTeachers {
isOnlyFirstTime := true
for _, member := range team.Members {
if member.PreviouslyParticipated {
isOnlyFirstTime = false
}
}
if onlyFirstTime && !isOnlyFirstTime {
continue
}

w.Write([]byte(team.Name + "\n"))
for _, member := range team.Members {
w.Write([]byte(" " + member.Name + " (" + member.Email + ")\n"))
}
}
}
Loading