Пример #1
0
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
}
Пример #2
0
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"),
	}
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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
}
Пример #12
0
func register(user model.User, sess *sessions.Session, req *http.Request) (interface{}, model.User) {
	outdata := &registerData{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
}