func schedToSchedTL(sched schedule.Schedule, u model.User) scheduleTpldata { loc := u.Location() schedtl := scheduleTpldata{ Start: sched.Start.In(loc).Format(bestTimeFmtEver), } if f := sched.Freq; f.Count > 0 { schedtl.RepetitionEnabled = true schedtl.Count = int(f.Count) switch f.Unit { case schedule.Minute: schedtl.UnitIsMinute = true case schedule.Hour: schedtl.UnitIsHour = true case schedule.Day: schedtl.UnitIsDay = true case schedule.Week: schedtl.UnitIsWeek = true case schedule.Month: schedtl.UnitIsMonth = true case schedule.Year: schedtl.UnitIsYear = true } } if end := sched.End; !end.IsZero() { schedtl.EndEnabled = true schedtl.End = end.In(loc).Format(bestTimeFmtEver) } return schedtl }
func jobToTpldata(job model.Job, user model.User) *jobTpldata { excerpt := string(job.Content()) if len(excerpt) > 100 { excerpt = string([]rune(excerpt)[0:100]) + " (...)" } return &jobTpldata{ ID: job.ID().String(), Subject: job.Subject(), Excerpt: excerpt, Next: job.Next().In(user.Location()).Format("2006-Jan-02 15:04:05"), } }
func jobs(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { if user == nil { return &jobsTpldata{Error: "You need to be logged in to do that.", Fatal: true}, user } outdata := new(jobsTpldata) if req.Method == "POST" { if err := req.ParseForm(); err != nil { outdata.Error = "Could not understand form data." goto listjobs } if req.FormValue("Delconfirm") != "yes" { goto listjobs } for _, _id := range req.Form["Jobs"] { id, err := db.ParseDBID(_id) if err != nil { outdata.Error = "Not all jobs could be deleted." continue } job, err := user.JobByID(id) if err != nil { outdata.Error = "Not all jobs could be deleted." continue } if job.Delete() != nil { outdata.Error = "Not all jobs could be deleted." continue } outdata.Success = "Jobs deleted." } } listjobs: jobs := user.Jobs() outdata.Jobs = make([]*jobTpldata, len(jobs)) for i, job := range jobs { outdata.Jobs[i] = jobToTpldata(job, user) } return outdata, user }
func login(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { outdata := &loginTpldata{} if user != nil { outdata.Success = "You are already logged in" return outdata, user } if req.Method != "POST" { return outdata, user } if err := req.ParseForm(); err != nil { outdata.Error = "Formdata corrupted. Please try again." return outdata, user } indata := new(loginFormdata) if err := formdec.Decode(indata, req.Form); (err != nil) || (indata.Mail == "") || (indata.Password == "") { outdata.Error = "Input data wrong or missing. Please fill in all values." return outdata, user } user, err := dbcon.UserByMail(indata.Mail) switch err { case nil: case model.NotFound: outdata.Error = "E-Mail or password was wrong." return outdata, nil default: log.Printf("Error while loding user data (login): %s", err) outdata.Error = "User data could not be loaded." return outdata, nil } if bcrypt.CompareHashAndPassword(user.PWHash(), []byte(indata.Password)) != nil { outdata.Error = "E-Mail or password was wrong." return outdata, nil } sess.Values["uid"] = user.ID().String() outdata.Success = "Login successful" return outdata, user }
func deleteacc(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { outdata := &msgTpldata{Title: "Delete Account"} if user == nil { outdata.Class = "error" outdata.Msg = "You need to be logged in to do that" return outdata, user } if err := user.Delete(); err != nil { log.Printf("Error while deleting account: %s", err) outdata.Class = "error" outdata.Msg = "An error occurred during deletion." return outdata, user } delete(sess.Values, "uid") outdata.Class = "success" outdata.Msg = "Account deleted." return outdata, user }
func forgotpw(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { if req.Method != "POST" { return &forgotpwTpldata{}, user } if err := req.ParseForm(); err != nil { return &forgotpwTpldata{Error: "Form data corrupted."}, user } email := req.FormValue("Mail") if email == "" { return &forgotpwTpldata{Error: "E-Mail must not be empty."}, user } user, err := dbcon.UserByMail(email) if err != nil { return &forgotpwTpldata{Error: "E-Mail not found."}, user } key := genAcCode() if err := user.SetActivationCode(key); err != nil { log.Printf("Could not store pwreset key: %s", err) return &forgotpwTpldata{Error: "Could not generate a keyword reset code."}, user } if !SendPwresetLink(user.Email(), key, user.ID()) { return &forgotpwTpldata{Error: "Could not send reset E-Mail."}, user } return &forgotpwTpldata{Success: "We sent you an E-Mail with further instructions."}, user }
func activate(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { outdata := &msgTpldata{Title: "Activate Account", Class: "error"} req.ParseForm() _userid := req.FormValue("U") code := req.FormValue("Code") if (_userid == "") || (code == "") { outdata.Msg = "User or code invalid. Check, if the activation link was correctly copied from the mail." return outdata, nil } userid, err := db.ParseDBID(_userid) if err != nil { outdata.Msg = "User or code invalid. Check, if the activation link was correctly copied from the mail." return outdata, nil } switch user, err = dbcon.UserByID(userid); err { case nil: case model.NotFound: outdata.Msg = "User not found." return outdata, nil default: log.Printf("Error while getting user by ID <%s>: %s", userid, err) outdata.Msg = "An unknown error occurred while loading user data." return outdata, nil } if user.ActivationCode() != code { outdata.Msg = "Wrong activation code." return outdata, nil } if err := user.SetActivationCode(""); err != nil { log.Printf("Error while resetting activation code: %s", err) outdata.Msg = "An unknown error occurred while activating the user." return outdata, nil } if err := user.SetActive(true); err != nil { log.Printf("Error while resetting activation code: %s", err) outdata.Msg = "An unknown error occurred while activating the user." return outdata, nil } outdata.Class = "success" outdata.Msg = "Account activated!" return outdata, nil }
func (jt *jobeditTpldata) interpretForm(form url.Values, u model.User) (subject string, content []byte, ms schedule.MultiSchedule, ok bool) { loc := u.Location() l1 := len(form["Start"]) l2 := len(form["RepetitionEnabled"]) l3 := len(form["Count"]) l4 := len(form["Unit"]) l5 := len(form["EndEnabled"]) l6 := len(form["End"]) if (l1 != l2) || (l2 != l3) || (l3 != l4) || (l4 != l5) || (l5 != l6) { jt.Error = "Form corrupted. Changes were not saved" ok = false return } subject = form.Get("Subject") content = []byte(form.Get("Content")) jt.Subject = subject jt.Content = string(content) ok = true for i, _start := range form["Start"] { if i >= maxSchedules { break } if _start == "" { continue } start, err := time.ParseInLocation(bestTimeFmtEver, _start, loc) if err != nil { ok = false continue } count := uint64(0) var unit schedule.TimeUnit var end time.Time if form["RepetitionEnabled"][i] == "yes" { if count, err = strconv.ParseUint(form["Count"][i], 10, 64); err != nil { ok = false continue } switch form["Unit"][i] { case "Minute": unit = schedule.Minute case "Hour": unit = schedule.Hour case "Day": unit = schedule.Day case "Week": unit = schedule.Week case "Month": unit = schedule.Month case "Year": unit = schedule.Year default: ok = false continue } if form["EndEnabled"][i] == "yes" { if end, err = time.ParseInLocation(bestTimeFmtEver, form["End"][i], loc); err != nil { ok = false continue } } } sched := schedule.Schedule{ Start: start, Freq: schedule.Frequency{ Count: uint(count), Unit: unit, }, End: end, } ms = append(ms, sched) jt.Schedules[i] = schedToSchedTL(sched, u) } if !ok { jt.Error = "Some schedules were wrong (wrong time format, negative repetition counts)" return } if len(ms) == 0 { jt.Error = "No schedule." ok = false } return }
func jobedit(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { if user == nil { return &jobeditTpldata{Error: "You need to be logged in to do that.", Fatal: true}, user } outdata := &jobeditTpldata{Schedules: make([]scheduleTpldata, maxSchedules)} // Try to load job, if given _id := mux.Vars(req)["ID"] var job model.Job if _id != "" { id, err := db.ParseDBID(_id) if err != nil { return &jobeditTpldata{Error: "Job not found", Fatal: true}, user } if job, err = user.JobByID(id); err != nil { return &jobeditTpldata{Error: "Job not found", Fatal: true}, user } } if job != nil { outdata.fillFromJob(job, user) } if req.Method == "POST" { if (job == nil) && (jobsLimit >= 0) && (user.CountJobs() >= jobsLimit) { outdata.Error = "You have reached the limit of jobs per user." outdata.Fatal = true return outdata, user } if err := req.ParseForm(); err != nil { outdata.Error = "Could not understand forma data." return outdata, user } subject, content, mc, ok := outdata.interpretForm(req.Form, user) if ok { next := mc.NextAfter(time.Now()) if next.IsZero() { outdata.Error = "The schedule would not send any mail." } else if job != nil { if logfail("setting subject", job.SetSubject(subject)) && logfail("setting content", job.SetContent(content)) && logfail("setting schedule", job.SetSchedule(mc)) && logfail("setting next", job.SetNext(next)) { outdata.Success = "Changes saved" } else { outdata.Error = "Could not save everything." } } else { if job, err := user.AddJob(subject, content, mc, next); logfail("creating new job", err) { outdata.fillFromJob(job, user) outdata.Success = "Job created" } else { outdata.Error = "Failed creating the job." } } } } return outdata, user }
func settings(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { if user == nil { return &settingsTpldata{Error: "You need to be logged in to do that.", Fatal: true}, nil } outdata := &settingsTpldata{Timezones: make(map[string]bool)} tznow := user.Location().String() for _, tz := range timeLocs { outdata.Timezones[tz] = (tz == tznow) } if req.Method != "POST" { return outdata, user } if err := req.ParseForm(); err != nil { outdata.Error = "Could not parse form" return outdata, user } switch req.FormValue("M") { case "setpasswd": if req.FormValue("Password") == "" { outdata.Error = "Password must not be empty." return outdata, user } if req.FormValue("Password") != req.FormValue("RepeatPassword") { outdata.Error = "Passwords must be equal." return outdata, user } hash, err := bcrypt.GenerateFromPassword([]byte(req.FormValue("Password")), bcrypt.DefaultCost) if err != nil { log.Printf("Error hashing password: %s", err) outdata.Error = "Error while saving password." return outdata.Error, user } if err := user.SetPWHash(hash); err != nil { log.Printf("Error setting pwhash: %s", err) outdata.Error = "Could not save new password." } else { outdata.Success = "Password changed" } case "settimezone": loc, err := time.LoadLocation(req.FormValue("Timezone")) if err != nil { outdata.Error = "Unknown Timezone" return outdata, user } if err := user.SetLocation(loc); err != nil { log.Printf("Error setting location: %s", err) outdata.Error = "Could not save new timezone." } else { outdata.Success = "New timezone saved." } } return outdata, user }
func pwreset(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { if err := req.ParseForm(); err != nil { return &pwresetTpldata{Error: "Form data corrupted."}, user } code := req.FormValue("Code") _uid := req.FormValue("U") pw1 := req.FormValue("Password") pw2 := req.FormValue("PasswordAgain") if code == "" { return &pwresetTpldata{Error: "Wrong password reset code"}, user } uid, err := db.ParseDBID(_uid) if err != nil { return &pwresetTpldata{Error: "Invalid user ID"}, user } if user, err = dbcon.UserByID(uid); err != nil { return &pwresetTpldata{Error: "User not found"}, user } if user.ActivationCode() != code { return &pwresetTpldata{Error: "Wrong activation code"}, user } outdata := &pwresetTpldata{UID: _uid, Code: code} if req.Method != "POST" { return outdata, user } if pw1 == "" { outdata.Error = "Password must not be empty." return outdata, user } if pw1 != pw2 { outdata.Error = "Passwords are not identical." return outdata, user } hash, err := bcrypt.GenerateFromPassword([]byte(pw1), bcrypt.DefaultCost) if err != nil { log.Printf("Could not has password: %s", err) outdata.Error = "Could not save password." return outdata, user } if err := user.SetPWHash(hash); err != nil { log.Printf("Error while hashing password: %s", err) outdata.Error = "Could not save password." return outdata, user } if err := user.SetActivationCode(""); err != nil { log.Printf("Error resetting acCode: %s", err) } outdata.Success = "Password was changed" return outdata, user }
func register(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) { outdata := ®isterData{Timezones: &timeLocs} if user != nil { outdata.Success = "You are already logged in. To register a new account, first log out." return outdata, user } if req.Method != "POST" { return outdata, user } if err := req.ParseForm(); err != nil { outdata.Error = "Form data corrupted." return outdata, user } indata := new(registerFormdata) if err := formdec.Decode(indata, req.Form); (err != nil) || (indata.Mail == "") || (indata.Timezone.Loc == nil) { outdata.Error = "Input data wrong or missing. Please fill in all values and make sure to provide a valid E-Mail address." return outdata, user } if indata.Password == "" { outdata.Error = "Empty passwords are not allowed." return outdata, user } if indata.Password != indata.RetypePassword { outdata.Error = "Passwords are not identical." return outdata, user } mail := string(indata.Mail) switch _, err := dbcon.UserByMail(mail); err { case nil: outdata.Error = "This E-Mail address is already used." return outdata, user case model.NotFound: default: log.Printf("Error while checking, if mail is used: %s", err) outdata.Error = "Internal error, sorry." return outdata, user } acCode := genAcCode() pwhash, err := bcrypt.GenerateFromPassword([]byte(indata.Password), bcrypt.DefaultCost) if err != nil { log.Printf("Error while hashing password: %s", err) outdata.Error = "Internal error, sorry." return outdata, user } user, err = dbcon.AddUser(mail, pwhash, indata.Timezone.Loc, false, acCode) if err != nil { log.Printf("Could not create user (%s): %s", indata.Mail, err) outdata.Error = "Internal error, sorry." return outdata, user } if !SendActivationcode(mail, acCode, user.ID()) { outdata.Error = "We could not send you a mail with your confirmation code." return outdata, user } outdata.Success = "Account created successfully! We sent you an E-Mail that contains a link to activate your account." return outdata, user }