Compare commits

...

4 Commits

Author SHA1 Message Date
Max Erenberg 0a74c04e84 add app_url documentation to README
continuous-integration/drone/pr Build is passing Details
2024-03-23 19:07:31 -04:00
Max Erenberg c35e3ff0d6 add hsts_max_age config option 2024-03-23 19:00:18 -04:00
Max Erenberg 24944793c8 add cookie_name config option 2024-03-23 18:47:44 -04:00
Max Erenberg 99bab0c201 add note about passwd to pwreset.html 2024-03-23 18:39:38 -04:00
5 changed files with 32 additions and 11 deletions

View File

@ -31,9 +31,14 @@ go run scripts/proxy.go -s app.sock -u ctdalek -f Calum
```
Now you should be able to visit http://localhost:9988 in your browser.
You can change the `-u` (username) and `-f` (first name) arguments to simulate
a different user. See the .drone/data.ldif file in the parent directory to see
all mock users.
NOTE: If you are not accessing the website via "localhost" (e.g. you are using
some custom proxy setup), then you need to modify the value of "app_url" in
dev.json. The app_url value must be equal to the base URL which you enter in
your browser's address bar, otherwise the cookie domain will not match.
You can change the `-u` (username) and `-f` (first name) arguments to the proxy.go
program to simulate a different user. See the .drone/data.ldif file in the parent
directory to see all mock users.
### Templates and static assets
In development, the templated views and static assets will be loaded from the

View File

@ -110,9 +110,7 @@ func NewAPI(cfg *config.Config, ceodSrv model.CeodService, mailSrv service.MailS
addStaticAssets(cfg.IsDev, e)
e.Use(appContextMiddleware(useFCGI(cfg), app))
e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// The cookie name needs to be very unique because this app is
// being served from the root CSC domain
TokenLookup: "cookie:ceod-web-csrf",
TokenLookup: "cookie:" + cfg.CookieName,
CookieName: "ceod-web-csrf",
CookiePath: cfg.GetAppPath(),
CookieDomain: cfg.GetAppHostname(),

View File

@ -4,17 +4,19 @@ import (
"errors"
"net/http"
"net/http/fcgi"
"strconv"
"strings"
"github.com/labstack/echo/v4"
"git.csclub.uwaterloo.ca/public/pyceo/web/internal/app"
"git.csclub.uwaterloo.ca/public/pyceo/web/internal/config"
"git.csclub.uwaterloo.ca/public/pyceo/web/pkg/logging"
)
func helmet(isDev bool) echo.MiddlewareFunc {
func helmet(cfg *config.Config) echo.MiddlewareFunc {
cspSchemes := "https:"
if isDev {
if cfg.IsDev {
cspSchemes = "http: https:"
}
cspDirectives := []string{
@ -29,7 +31,7 @@ func helmet(isDev bool) echo.MiddlewareFunc {
"script-src-attr 'none'",
"style-src 'self' " + cspSchemes + " 'unsafe-inline'",
}
if !isDev {
if !cfg.IsDev {
cspDirectives = append(cspDirectives, "upgrade-insecure-requests")
}
csp := strings.Join(cspDirectives, ";")
@ -40,8 +42,11 @@ func helmet(isDev bool) echo.MiddlewareFunc {
h.Set("Cross-Origin-Opener-Policy", "same-origin")
h.Set("Cross-Origin-Resource-Policy", "same-origin")
h.Set(echo.HeaderReferrerPolicy, "no-referrer")
if !isDev {
h.Set(echo.HeaderStrictTransportSecurity, "max-age=15552000")
if cfg.HstsMaxAge != 0 {
h.Set(
echo.HeaderStrictTransportSecurity,
"max-age="+strconv.FormatInt(int64(cfg.HstsMaxAge), 10),
)
}
return next(c)
}

View File

@ -11,6 +11,9 @@ import (
const (
defaultKrb5Config = "/etc/krb5.conf"
defaultKrb5KtName = "/etc/krb5.keytab"
// The cookie name needs to be very unique because this app is
// being served from the root CSC domain
defaultCookieName = "ceod-web-csrf"
ceodHostname = "phosphoric-acid"
ceodPort = 9987
)
@ -23,6 +26,8 @@ type Config struct {
CSCDomain string `json:"csc_domain"`
UWDomain string `json:"uw_domain"`
MTA string `json:"mta"`
CookieName string `json:"cookie_name"`
HstsMaxAge int `json:"hsts_max_age"`
IsDev bool `json:"dev"`
ForcedEmailRecipient string `json:"forced_email_recipient"`
@ -79,6 +84,9 @@ func NewConfig(cfgPath string) *Config {
} else if cfg.appPath[len(cfg.appPath)-1] != '/' {
cfg.appPath += "/"
}
if cfg.CookieName == "" {
cfg.CookieName = defaultCookieName
}
if !cfg.IsDev && cfg.MTA == "" {
panic(fmt.Errorf(`"mta" is missing from %s`, cfgPath))
}

View File

@ -1,5 +1,10 @@
{{ define "title" }}Password Reset{{ end }}
{{ define "main" }}
<p>
<strong>NOTE</strong>: if you are able to SSH into a general-use machine
using a public key, then you do not need to use this form. Simply run
<code>passwd</code> instead.
</p>
<p>
Clicking the button below will generate a new temporary password for your
account which will be sent to the following email address: