171 lines
4.7 KiB
Go
171 lines
4.7 KiB
Go
/*
|
|
Copyright 2017-2022 CAcert Inc.
|
|
SPDX-License-Identifier: Apache-2.0
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
minimumContentLen = 3
|
|
minimumTitleLen = 3
|
|
base10 = 10
|
|
size8Bit = 8
|
|
size64Bit = 64
|
|
)
|
|
|
|
const (
|
|
hoursInADay = 24
|
|
dueThreeDays = 3
|
|
dueOneWeek = 7
|
|
dueTwoWeeks = 14
|
|
dueFourWeeks = 28
|
|
)
|
|
|
|
var validDueDurations = map[string]time.Duration{
|
|
"+3 days": time.Hour * hoursInADay * dueThreeDays,
|
|
"+7 days": time.Hour * hoursInADay * dueOneWeek,
|
|
"+14 days": time.Hour * hoursInADay * dueTwoWeeks,
|
|
"+28 days": time.Hour * hoursInADay * dueFourWeeks,
|
|
}
|
|
|
|
type NewDecisionForm struct {
|
|
Title string
|
|
Content string
|
|
VoteType string
|
|
Due string
|
|
Errors map[string]string
|
|
}
|
|
|
|
func (f *NewDecisionForm) Validate() (bool, *Decision) {
|
|
f.Errors = make(map[string]string)
|
|
|
|
data := &Decision{}
|
|
|
|
data.Title = strings.TrimSpace(f.Title)
|
|
if len(data.Title) < minimumTitleLen {
|
|
f.Errors["Title"] = fmt.Sprintf("Please enter at least %d characters for Title.", minimumTitleLen)
|
|
}
|
|
|
|
data.Content = strings.TrimSpace(f.Content)
|
|
if len(strings.Fields(data.Content)) < minimumContentLen {
|
|
f.Errors["Content"] = fmt.Sprintf("Please enter at least %d words as Text.", minimumContentLen)
|
|
}
|
|
|
|
if voteType, err := strconv.ParseUint(f.VoteType, base10, size8Bit); err != nil || (voteType != 0 && voteType != 1) {
|
|
f.Errors["VoteType"] = fmt.Sprint("Please choose a valid vote type.", err)
|
|
} else {
|
|
data.VoteType = VoteType(uint8(voteType))
|
|
}
|
|
|
|
if dueDuration, ok := validDueDurations[f.Due]; !ok {
|
|
f.Errors["Due"] = "Please choose a valid due date."
|
|
} else {
|
|
year, month, day := time.Now().UTC().Add(dueDuration).Date()
|
|
data.Due = time.Date(year, month, day, 23, 59, 59, 0, time.UTC)
|
|
}
|
|
|
|
return len(f.Errors) == 0, data
|
|
}
|
|
|
|
type EditDecisionForm struct {
|
|
Title string
|
|
Content string
|
|
VoteType string
|
|
Due string
|
|
Decision *Decision
|
|
Errors map[string]string
|
|
}
|
|
|
|
func (f *EditDecisionForm) Validate() (bool, *Decision) {
|
|
f.Errors = make(map[string]string)
|
|
|
|
data := f.Decision
|
|
|
|
data.Title = strings.TrimSpace(f.Title)
|
|
if len(data.Title) < minimumTitleLen {
|
|
f.Errors["Title"] = fmt.Sprintf("Please enter at least %d characters for Title.", minimumTitleLen)
|
|
}
|
|
|
|
data.Content = strings.TrimSpace(f.Content)
|
|
if len(strings.Fields(data.Content)) < minimumContentLen {
|
|
f.Errors["Content"] = fmt.Sprintf("Please enter at least %d words as Text.", minimumContentLen)
|
|
}
|
|
|
|
if voteType, err := strconv.ParseUint(f.VoteType, base10, size8Bit); err != nil || (voteType != 0 && voteType != 1) {
|
|
f.Errors["VoteType"] = fmt.Sprint("Please choose a valid vote type.", err)
|
|
} else {
|
|
data.VoteType = VoteType(uint8(voteType))
|
|
}
|
|
|
|
if dueDuration, ok := validDueDurations[f.Due]; !ok {
|
|
f.Errors["Due"] = "Please choose a valid due date."
|
|
} else {
|
|
year, month, day := time.Now().UTC().Add(dueDuration).Date()
|
|
data.Due = time.Date(year, month, day, 23, 59, 59, 0, time.UTC)
|
|
}
|
|
|
|
return len(f.Errors) == 0, data
|
|
}
|
|
|
|
type ProxyVoteForm struct {
|
|
Voter string
|
|
Vote string
|
|
Justification string
|
|
Errors map[string]string
|
|
}
|
|
|
|
func (f *ProxyVoteForm) Validate() (bool, *Voter, *Vote, string) {
|
|
f.Errors = make(map[string]string)
|
|
|
|
const minimumJustificationLen = 3
|
|
|
|
var (
|
|
voter *Voter
|
|
err error
|
|
voterID, vote int64
|
|
)
|
|
|
|
data := &Vote{}
|
|
|
|
if voterID, err = strconv.ParseInt(f.Voter, base10, size64Bit); err != nil {
|
|
f.Errors["Voter"] = fmt.Sprintf("Please choose a valid voter: %v.", err)
|
|
} else if voter, err = GetVoterByID(voterID); err != nil {
|
|
f.Errors["Voter"] = fmt.Sprintf("Please choose a valid voter: %v.", err)
|
|
} else {
|
|
data.VoterID = voter.ID
|
|
}
|
|
|
|
if vote, err = strconv.ParseInt(f.Vote, base10, size8Bit); err != nil {
|
|
f.Errors["Vote"] = fmt.Sprintf("Please choose a valid vote: %v.", err)
|
|
} else if voteChoice, ok := VoteChoices[vote]; !ok {
|
|
f.Errors["Vote"] = "Please choose a valid vote."
|
|
} else {
|
|
data.Vote = voteChoice
|
|
}
|
|
|
|
justification := strings.TrimSpace(f.Justification)
|
|
if len(justification) < minimumJustificationLen {
|
|
f.Errors["Justification"] = "Please enter at least 3 characters for justification."
|
|
}
|
|
|
|
return len(f.Errors) == 0, voter, data, justification
|
|
}
|