Compare commits
No commits in common. "main" and "0.8.0" have entirely different histories.
33 changed files with 1383 additions and 175 deletions
|
@ -1,9 +1,7 @@
|
||||||
---
|
---
|
||||||
run:
|
run:
|
||||||
go: "1.22"
|
go: "1.17"
|
||||||
|
skip-files:
|
||||||
issues:
|
|
||||||
exclude-files:
|
|
||||||
- boardvoting/assets.go
|
- boardvoting/assets.go
|
||||||
|
|
||||||
output:
|
output:
|
||||||
|
@ -15,7 +13,7 @@ linters-settings:
|
||||||
const:
|
const:
|
||||||
ORGANIZATION: CAcert Inc.
|
ORGANIZATION: CAcert Inc.
|
||||||
template: |-
|
template: |-
|
||||||
Copyright {{ ORGANIZATION }}
|
Copyright {{ YEAR-RANGE }} {{ ORGANIZATION }}
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -29,8 +27,8 @@ linters-settings:
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
mnd:
|
gomnd:
|
||||||
ignored-functions:
|
ignore-functions:
|
||||||
- 'strconv.*'
|
- 'strconv.*'
|
||||||
ignored-numbers:
|
ignored-numbers:
|
||||||
- '-1,0,1,2,8'
|
- '-1,0,1,2,8'
|
||||||
|
@ -59,7 +57,7 @@ linters:
|
||||||
- gofmt
|
- gofmt
|
||||||
- goheader
|
- goheader
|
||||||
- goimports
|
- goimports
|
||||||
- mnd
|
- gomnd
|
||||||
- gosec
|
- gosec
|
||||||
- lll
|
- lll
|
||||||
- makezero
|
- makezero
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# This is an example .goreleaser.yml file with some sane defaults.
|
# This is an example .goreleaser.yml file with some sane defaults.
|
||||||
# Make sure to check the documentation at http://goreleaser.com
|
# Make sure to check the documentation at http://goreleaser.com
|
||||||
project_name: cacert-boardvoting
|
project_name: cacert-boardvoting
|
||||||
version: 2
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
|
@ -18,6 +17,11 @@ builds:
|
||||||
- -trimpath
|
- -trimpath
|
||||||
- -v
|
- -v
|
||||||
main: ./cmd/boardvoting
|
main: ./cmd/boardvoting
|
||||||
|
archives:
|
||||||
|
- replacements:
|
||||||
|
linux: Linux
|
||||||
|
amd64: x86_64
|
||||||
|
format: binary
|
||||||
checksum:
|
checksum:
|
||||||
name_template: 'checksums.txt'
|
name_template: 'checksums.txt'
|
||||||
snapshot:
|
snapshot:
|
||||||
|
|
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
|
@ -1,6 +1,6 @@
|
||||||
#!groovy
|
#!groovy
|
||||||
/*
|
/*
|
||||||
Copyright 2017-2023 Jan Dittberner
|
Copyright 2017-2022 Jan Dittberner
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this program except in compliance with the License.
|
you may not use this program except in compliance with the License.
|
||||||
|
@ -18,7 +18,7 @@ pipeline {
|
||||||
agent any
|
agent any
|
||||||
|
|
||||||
tools {
|
tools {
|
||||||
go "go-1.19"
|
go "go-1.18"
|
||||||
}
|
}
|
||||||
|
|
||||||
environment {
|
environment {
|
||||||
|
|
|
@ -53,7 +53,7 @@ Last Changed Date: 2009-07-12 04:02:38 +0000 (Sun, 12 Jul 2009)
|
||||||
|
|
||||||
Local development requires
|
Local development requires
|
||||||
|
|
||||||
* golang >= 1.19
|
* golang >= 1.18
|
||||||
* sqlite3 and development headers
|
* sqlite3 and development headers
|
||||||
* GNU make
|
* GNU make
|
||||||
* nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Fomantic-UI] CSS and JavaScript)
|
* nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Fomantic-UI] CSS and JavaScript)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -7,7 +7,6 @@ mail_config:
|
||||||
smtp_host: localhost
|
smtp_host: localhost
|
||||||
smtp_port: 25
|
smtp_port: 25
|
||||||
base_url: https://motions.cacert.org
|
base_url: https://motions.cacert.org
|
||||||
message_id_domain: motions.cacert.org
|
|
||||||
notice_mail_address: cacert-board@lists.cacert.org
|
notice_mail_address: cacert-board@lists.cacert.org
|
||||||
vote_notice_mail_address: cacert-board-votes@lists.cacert.org
|
vote_notice_mail_address: cacert-board-votes@lists.cacert.org
|
||||||
notification_sender_address: returns@cacert.org
|
notification_sender_address: returns@cacert.org
|
||||||
|
|
44
go.mod
44
go.mod
|
@ -1,46 +1,46 @@
|
||||||
module git.cacert.org/cacert-boardvoting
|
module git.cacert.org/cacert-boardvoting
|
||||||
|
|
||||||
go 1.22
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3
|
github.com/Masterminds/sprig/v3 v3.2.2
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1
|
github.com/golang-migrate/migrate/v4 v4.15.2
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/huandu/xstrings v1.5.0 // indirect
|
github.com/huandu/xstrings v1.3.2 // indirect
|
||||||
github.com/imdario/mergo v0.3.16 // indirect
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
github.com/jmoiron/sqlx v1.4.0
|
github.com/jmoiron/sqlx v1.3.5
|
||||||
github.com/johejo/golang-migrate-extra v0.0.0-20211005021153-c17dd75f8b4a
|
github.com/johejo/golang-migrate-extra v0.0.0-20211005021153-c17dd75f8b4a
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
github.com/mattn/go-sqlite3 v1.14.12
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/vearutop/statigz v1.4.0
|
github.com/vearutop/statigz v1.1.8
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/mail.v2 v2.3.1
|
gopkg.in/mail.v2 v2.3.1
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexedwards/scs/sqlite3store v0.0.0-20240316134038-7e11d57e8885
|
github.com/alexedwards/scs/sqlite3store v0.0.0-20220216073957-c252878bcf5a
|
||||||
github.com/alexedwards/scs/v2 v2.8.0
|
github.com/alexedwards/scs/v2 v2.5.0
|
||||||
github.com/go-chi/chi/v5 v5.0.12
|
github.com/go-chi/chi/v5 v5.0.7
|
||||||
github.com/go-playground/form/v4 v4.2.1
|
github.com/go-playground/form/v4 v4.2.0
|
||||||
github.com/justinas/nosurf v1.1.1
|
github.com/justinas/nosurf v1.1.1
|
||||||
github.com/lestrrat-go/tcputil v0.0.0-20180223003554-d3c7f98154fb
|
github.com/lestrrat-go/tcputil v0.0.0-20180223003554-d3c7f98154fb
|
||||||
github.com/stretchr/testify v1.8.3
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/text v0.16.0
|
golang.org/x/text v0.3.7
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/shopspring/decimal v1.4.0 // indirect
|
github.com/shopspring/decimal v1.3.1 // indirect
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
github.com/spf13/cast v1.4.1 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -199,10 +199,12 @@ func (app *Application) Routes() http.Handler {
|
||||||
r.Get("/newmotion/", motionHandler.NewForm)
|
r.Get("/newmotion/", motionHandler.NewForm)
|
||||||
r.Post("/newmotion/", motionHandler.New)
|
r.Post("/newmotion/", motionHandler.New)
|
||||||
|
|
||||||
r.Get("/motions/{tag}/edit", motionHandler.EditForm)
|
r.Route("/motions/{tag}", func(r chi.Router) {
|
||||||
r.Post("/motions/{tag}/edit", motionHandler.Edit)
|
r.Get("/edit", motionHandler.EditForm)
|
||||||
r.Get("/motions/{tag}/withdraw", motionHandler.WithdrawForm)
|
r.Post("/edit", motionHandler.Edit)
|
||||||
r.Post("/motions/{tag}/withdraw", motionHandler.Withdraw)
|
r.Get("/withdraw", motionHandler.WithdrawForm)
|
||||||
|
r.Post("/withdraw", motionHandler.Withdraw)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -33,8 +33,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
|
|
||||||
"git.cacert.org/cacert-boardvoting/internal/notifications"
|
"git.cacert.org/cacert-boardvoting/internal/notifications"
|
||||||
|
|
||||||
"git.cacert.org/cacert-boardvoting/internal/models"
|
"git.cacert.org/cacert-boardvoting/internal/models"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -62,7 +62,7 @@ func Test_secureHeaders(t *testing.T) {
|
||||||
|
|
||||||
SecureHeaders(next).ServeHTTP(rr, r)
|
SecureHeaders(next).ServeHTTP(rr, r)
|
||||||
|
|
||||||
rs := rr.Result()
|
rs := rr.Result() //nolint:bodyclose // linters bug
|
||||||
|
|
||||||
defer func() { _ = rs.Body.Close() }()
|
defer func() { _ = rs.Body.Close() }()
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ func TestApplication_tryAuthenticate(t *testing.T) {
|
||||||
|
|
||||||
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
||||||
|
|
||||||
rs := rr.Result()
|
rs := rr.Result() //nolint:bodyclose // linters bug
|
||||||
|
|
||||||
defer func() { _ = rs.Body.Close() }()
|
defer func() { _ = rs.Body.Close() }()
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ func TestApplication_tryAuthenticate(t *testing.T) {
|
||||||
|
|
||||||
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
||||||
|
|
||||||
rs := rr.Result()
|
rs := rr.Result() //nolint:bodyclose // linters bug
|
||||||
|
|
||||||
defer func() { _ = rs.Body.Close() }()
|
defer func() { _ = rs.Body.Close() }()
|
||||||
|
|
||||||
|
@ -158,12 +158,11 @@ func TestApplication_tryAuthenticate(t *testing.T) {
|
||||||
|
|
||||||
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
mw.TryAuthenticate(next).ServeHTTP(rr, r)
|
||||||
|
|
||||||
rs := rr.Result()
|
rs := rr.Result() //nolint:bodyclose // linters bug
|
||||||
|
|
||||||
defer func() { _ = rs.Body.Close() }()
|
defer func() { _ = rs.Body.Close() }()
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, rs.StatusCode)
|
assert.Equal(t, http.StatusOK, rs.StatusCode)
|
||||||
|
|
||||||
user := nextCtx.Value(ctxUser)
|
user := nextCtx.Value(ctxUser)
|
||||||
|
|
||||||
assert.NotNil(t, user)
|
assert.NotNil(t, user)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -34,10 +34,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkRole(v *models.User, roles ...models.RoleName) (bool, error) {
|
func checkRole(v *models.User, roles ...models.RoleName) (bool, error) {
|
||||||
if v == nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRole, err := v.HasRole(roles...)
|
hasRole, err := v.HasRole(roles...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("could not determine user roles: %w", err)
|
return false, fmt.Errorf("could not determine user roles: %w", err)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -47,6 +47,7 @@ func (r *RemindVotersJob) Schedule() {
|
||||||
year, month, day := now.Date()
|
year, month, day := now.Date()
|
||||||
|
|
||||||
nextPotentialRun := time.Date(year, month, day+1, 0, 0, 0, 0, time.UTC)
|
nextPotentialRun := time.Date(year, month, day+1, 0, 0, 0, 0, time.UTC)
|
||||||
|
nextPotentialRun.Add(hoursInDay * time.Hour)
|
||||||
|
|
||||||
relevantDue := nextPotentialRun.Add(reminderDays * hoursInDay * time.Hour)
|
relevantDue := nextPotentialRun.Add(reminderDays * hoursInDay * time.Hour)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -458,15 +458,13 @@ func sumsForDecision(ctx context.Context, tx *sqlx.Tx, d *Motion) (*VoteSums, er
|
||||||
return nil, fmt.Errorf("could not parse row for vote sums of motion %s: %w", d.Tag, err)
|
return nil, fmt.Errorf("could not parse row for vote sums of motion %s: %w", d.Tag, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch vote.ID {
|
switch vote {
|
||||||
case VoteAye.ID:
|
case VoteAye:
|
||||||
sums.Ayes = count
|
sums.Ayes = count
|
||||||
case VoteNaye.ID:
|
case VoteNaye:
|
||||||
sums.Nayes = count
|
sums.Nayes = count
|
||||||
case VoteAbstain.ID:
|
case VoteAbstain:
|
||||||
sums.Abstains = count
|
sums.Abstains = count
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown vote type '%+v'", vote)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,12 +605,12 @@ func (m *MotionModel) List(ctx context.Context, options *MotionListOptions) ([]*
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) error {
|
func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) error {
|
||||||
decisionIDs := make([]int64, len(decisions))
|
decisionIds := make([]int64, len(decisions))
|
||||||
decisionMap := make(map[int64]*Motion, len(decisions))
|
decisionMap := make(map[int64]*Motion, len(decisions))
|
||||||
|
|
||||||
for idx, decision := range decisions {
|
for idx, decision := range decisions {
|
||||||
decision.Sums = &VoteSums{}
|
decision.Sums = &VoteSums{}
|
||||||
decisionIDs[idx] = decision.ID
|
decisionIds[idx] = decision.ID
|
||||||
decisionMap[decision.ID] = decision
|
decisionMap[decision.ID] = decision
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +619,7 @@ func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) err
|
||||||
FROM votes v
|
FROM votes v
|
||||||
WHERE v.decision IN (?)
|
WHERE v.decision IN (?)
|
||||||
GROUP BY v.decision, v.vote`,
|
GROUP BY v.decision, v.vote`,
|
||||||
decisionIDs,
|
decisionIds,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create IN query: %w", err)
|
return fmt.Errorf("could not create IN query: %w", err)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -251,10 +251,6 @@ WHERE e.address IN (?)`, emails)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.roles, err = m.Roles(ctx, &user); err != nil {
|
if user.roles, err = m.Roles(ctx, &user); err != nil {
|
||||||
return nil, fmt.Errorf("could not retrieve roles for user %s: %w", user.Name, err)
|
return nil, fmt.Errorf("could not retrieve roles for user %s: %w", user.Name, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2017-2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -38,7 +38,6 @@ type MailConfig struct {
|
||||||
SMTPHost string `yaml:"smtp_host"`
|
SMTPHost string `yaml:"smtp_host"`
|
||||||
SMTPPort int `yaml:"smtp_port"`
|
SMTPPort int `yaml:"smtp_port"`
|
||||||
SMTPTimeOut time.Duration `yaml:"smtp_timeout,omitempty"`
|
SMTPTimeOut time.Duration `yaml:"smtp_timeout,omitempty"`
|
||||||
Domain string `yaml:"message_id_domain"`
|
|
||||||
NotificationSenderAddress string `yaml:"notification_sender_address"`
|
NotificationSenderAddress string `yaml:"notification_sender_address"`
|
||||||
NoticeMailAddress string `yaml:"notice_mail_address"`
|
NoticeMailAddress string `yaml:"notice_mail_address"`
|
||||||
VoteNoticeMailAddress string `yaml:"vote_notice_mail_address"`
|
VoteNoticeMailAddress string `yaml:"vote_notice_mail_address"`
|
||||||
|
@ -203,10 +202,10 @@ func voteNoticeRecipient(mc *MailConfig) recipientData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func motionReplyHeaders(m *models.Motion, mc *MailConfig) map[string][]string {
|
func motionReplyHeaders(m *models.Motion) map[string][]string {
|
||||||
return map[string][]string{
|
return map[string][]string{
|
||||||
"References": {fmt.Sprintf("<%s@%s>", m.Tag, mc.Domain)},
|
"References": {fmt.Sprintf("<%s>", m.Tag)},
|
||||||
"In-Reply-To": {fmt.Sprintf("<%s@%s>", m.Tag, mc.Domain)},
|
"In-Reply-To": {fmt.Sprintf("<%s>", m.Tag)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +247,7 @@ func (c *ClosedDecisionNotification) GetNotificationContent(mc *MailConfig) *Not
|
||||||
*models.Motion
|
*models.Motion
|
||||||
}{Motion: c.Decision},
|
}{Motion: c.Decision},
|
||||||
subject: fmt.Sprintf("Re: %s - %s - finalized", c.Decision.Tag, c.Decision.Title),
|
subject: fmt.Sprintf("Re: %s - %s - finalized", c.Decision.Tag, c.Decision.Title),
|
||||||
headers: motionReplyHeaders(c.Decision, mc),
|
headers: motionReplyHeaders(c.Decision),
|
||||||
recipients: []recipientData{defaultRecipient(mc)},
|
recipients: []recipientData{defaultRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,14 +275,14 @@ func (n NewDecisionNotification) GetNotificationContent(mc *MailConfig) *Notific
|
||||||
UnvotedURL: unvotedURL,
|
UnvotedURL: unvotedURL,
|
||||||
},
|
},
|
||||||
subject: fmt.Sprintf("%s - %s", n.Decision.Tag, n.Decision.Title),
|
subject: fmt.Sprintf("%s - %s", n.Decision.Tag, n.Decision.Title),
|
||||||
headers: n.getHeaders(mc),
|
headers: n.getHeaders(),
|
||||||
recipients: []recipientData{defaultRecipient(mc)},
|
recipients: []recipientData{defaultRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n NewDecisionNotification) getHeaders(mc *MailConfig) map[string][]string {
|
func (n NewDecisionNotification) getHeaders() map[string][]string {
|
||||||
return map[string][]string{
|
return map[string][]string{
|
||||||
"Message-ID": {fmt.Sprintf("<%s@%s>", n.Decision.Tag, mc.Domain)},
|
"Message-ID": {fmt.Sprintf("<%s>", n.Decision.Tag)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +309,7 @@ func (u UpdateDecisionNotification) GetNotificationContent(mc *MailConfig) *Noti
|
||||||
UnvotedURL: unvotedURL,
|
UnvotedURL: unvotedURL,
|
||||||
},
|
},
|
||||||
subject: fmt.Sprintf("%s - %s", u.Decision.Tag, u.Decision.Title),
|
subject: fmt.Sprintf("%s - %s", u.Decision.Tag, u.Decision.Title),
|
||||||
headers: motionReplyHeaders(u.Decision, mc),
|
headers: motionReplyHeaders(u.Decision),
|
||||||
recipients: []recipientData{defaultRecipient(mc)},
|
recipients: []recipientData{defaultRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +333,7 @@ func (d DirectVoteNotification) GetNotificationContent(mc *MailConfig) *Notifica
|
||||||
Choice: d.Choice,
|
Choice: d.Choice,
|
||||||
},
|
},
|
||||||
subject: fmt.Sprintf("Re: %s - %s", d.Decision.Tag, d.Decision.Title),
|
subject: fmt.Sprintf("Re: %s - %s", d.Decision.Tag, d.Decision.Title),
|
||||||
headers: motionReplyHeaders(d.Decision, mc),
|
headers: motionReplyHeaders(d.Decision),
|
||||||
recipients: []recipientData{voteNoticeRecipient(mc)},
|
recipients: []recipientData{voteNoticeRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,7 +363,7 @@ func (p ProxyVoteNotification) GetNotificationContent(mc *MailConfig) *Notificat
|
||||||
Justification: p.Justification,
|
Justification: p.Justification,
|
||||||
},
|
},
|
||||||
subject: fmt.Sprintf("Re: %s - %s", p.Decision.Tag, p.Decision.Title),
|
subject: fmt.Sprintf("Re: %s - %s", p.Decision.Tag, p.Decision.Title),
|
||||||
headers: motionReplyHeaders(p.Decision, mc),
|
headers: motionReplyHeaders(p.Decision),
|
||||||
recipients: []recipientData{voteNoticeRecipient(mc)},
|
recipients: []recipientData{voteNoticeRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +381,7 @@ func (w WithDrawMotionNotification) GetNotificationContent(mc *MailConfig) *Noti
|
||||||
Name string
|
Name string
|
||||||
}{Motion: w.Motion, Name: w.Voter.Name},
|
}{Motion: w.Motion, Name: w.Voter.Name},
|
||||||
subject: fmt.Sprintf("Re: %s - %s", w.Motion.Tag, w.Motion.Title),
|
subject: fmt.Sprintf("Re: %s - %s", w.Motion.Tag, w.Motion.Title),
|
||||||
headers: motionReplyHeaders(w.Motion, mc),
|
headers: motionReplyHeaders(w.Motion),
|
||||||
recipients: []recipientData{defaultRecipient(mc)},
|
recipients: []recipientData{defaultRecipient(mc)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright CAcert Inc.
|
Copyright 2022 CAcert Inc.
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
{{ with .User }}
|
{{ with .User }}
|
||||||
<div class="ui label">
|
<div class="ui label">
|
||||||
<i class="id card outline icon"></i>
|
<i class="id card outline icon"></i>
|
||||||
Authenticated as {{ .Name }} <{{ .Reminder.String }}>
|
Authenticated as {{ .Name }} <{{ .Reminder }}>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</main>
|
</main>
|
||||||
<footer class="ui vertical footer segment">
|
<footer class="ui vertical footer segment">
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
<span class="ui small text">© 2017-2023 CAcert Inc.</span>
|
<span class="ui small text">© 2017-2022 CAcert Inc.</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue