Add more helper functions

This commit is contained in:
adnano 2020-09-27 21:13:42 -04:00
parent fdf6bbc62f
commit 3c9821d812
4 changed files with 72 additions and 34 deletions

View File

@ -85,7 +85,7 @@ func login(rw *gmi.ResponseWriter, req *gmi.Request) {
rw.WriteHeader(gmi.StatusRedirect, "/login/password")
}
} else {
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
}
}
@ -93,7 +93,7 @@ func loginPassword(rw *gmi.ResponseWriter, req *gmi.Request) {
if len(req.TLS.PeerCertificates) > 0 {
session, ok := getSession(req.TLS.PeerCertificates[0])
if !ok {
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Not authorized")
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Not authorized")
return
}
@ -109,7 +109,7 @@ func loginPassword(rw *gmi.ResponseWriter, req *gmi.Request) {
}
}
} else {
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
}
}
@ -126,7 +126,7 @@ func profile(rw *gmi.ResponseWriter, req *gmi.Request) {
if len(req.TLS.PeerCertificates) > 0 {
session, ok := getSession(req.TLS.PeerCertificates[0])
if !ok {
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Certificate not authorized")
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Certificate not authorized")
return
}
user := logins[session.username]
@ -134,7 +134,7 @@ func profile(rw *gmi.ResponseWriter, req *gmi.Request) {
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
rw.Write([]byte(profile))
} else {
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
}
}
@ -142,17 +142,17 @@ func admin(rw *gmi.ResponseWriter, req *gmi.Request) {
if len(req.TLS.PeerCertificates) > 0 {
session, ok := getSession(req.TLS.PeerCertificates[0])
if !ok {
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Certificate not authorized")
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Certificate not authorized")
return
}
user := logins[session.username]
if !user.admin {
rw.WriteHeader(gmi.StatusCertificateNotAuthorised, "Admins only!")
rw.WriteHeader(gmi.StatusCertificateNotAuthorized, "Admins only!")
return
}
rw.WriteHeader(gmi.StatusSuccess, "text/gemini")
rw.Write([]byte("Welcome to the admin portal.\n"))
} else {
rw.WriteHeader(gmi.StatusClientCertificateRequired, "Certificate required")
rw.WriteHeader(gmi.StatusCertificateRequired, "Certificate required")
}
}

View File

@ -54,6 +54,7 @@ func sendRequest(req *gmi.Request) error {
return err
}
// TODO: More fine-grained analysis of the status code.
switch resp.Status / 10 {
case gmi.StatusClassInput:
fmt.Printf("%s: ", resp.Meta)
@ -78,7 +79,7 @@ func sendRequest(req *gmi.Request) error {
return fmt.Errorf("Temporary failure: %s", resp.Meta)
case gmi.StatusClassPermanentFailure:
return fmt.Errorf("Permanent failure: %s", resp.Meta)
case gmi.StatusClassClientCertificateRequired:
case gmi.StatusClassCertificateRequired:
fmt.Println("Generating client certificate for", req.Hostname())
return nil // TODO: Generate and store client certificate
}

View File

@ -7,34 +7,34 @@ import (
// Status codes.
const (
StatusInput = 10
StatusSensitiveInput = 11
StatusSuccess = 20
StatusRedirect = 30
StatusRedirectPermanent = 31
StatusTemporaryFailure = 40
StatusServerUnavailable = 41
StatusCGIError = 42
StatusProxyError = 43
StatusSlowDown = 44
StatusPermanentFailure = 50
StatusNotFound = 51
StatusGone = 52
StatusProxyRequestRefused = 53
StatusBadRequest = 59
StatusClientCertificateRequired = 60
StatusCertificateNotAuthorised = 61
StatusCertificateNotValid = 62
StatusInput = 10
StatusSensitiveInput = 11
StatusSuccess = 20
StatusRedirect = 30
StatusRedirectPermanent = 31
StatusTemporaryFailure = 40
StatusServerUnavailable = 41
StatusCGIError = 42
StatusProxyError = 43
StatusSlowDown = 44
StatusPermanentFailure = 50
StatusNotFound = 51
StatusGone = 52
StatusProxyRequestRefused = 53
StatusBadRequest = 59
StatusCertificateRequired = 60
StatusCertificateNotAuthorized = 61
StatusCertificateNotValid = 62
)
// Status code categories.
const (
StatusClassInput = 1
StatusClassSuccess = 2
StatusClassRedirect = 3
StatusClassTemporaryFailure = 4
StatusClassPermanentFailure = 5
StatusClassClientCertificateRequired = 6
StatusClassInput = 1
StatusClassSuccess = 2
StatusClassRedirect = 3
StatusClassTemporaryFailure = 4
StatusClassPermanentFailure = 5
StatusClassCertificateRequired = 6
)
var (

View File

@ -174,7 +174,7 @@ type Handler interface {
Serve(*ResponseWriter, *Request)
}
// NotFound replies to the request with a NotFound status code.
// NotFound replies to the request with the NotFound status code.
func NotFound(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusNotFound, "Not found")
}
@ -185,6 +185,17 @@ func NotFoundHandler() Handler {
return HandlerFunc(NotFound)
}
// Gone replies to the request with the Gone status code.
func Gone(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusGone, "Gone")
}
// GoneHandler returns a simple handler that responds to each request with
// the status code Gone.
func GoneHandler() Handler {
return HandlerFunc(Gone)
}
// Redirect replies to the request with a redirect to the given url.
// If permanent is true, Redirect will respond with a permanent redirect.
func Redirect(rw *ResponseWriter, req *Request, url string, permanent bool) {
@ -217,6 +228,32 @@ func InputHandler(prompt string) Handler {
})
}
// Sensitive responds to the request with a request for sensitive input
// using the given prompt.
func SensitiveInput(rw *ResponseWriter, req *Request, prompt string) {
rw.WriteHeader(StatusSensitiveInput, prompt)
}
// SensitiveInputHandler returns a simpler handler that responds to each request
// with a request for sensitive input.
func SensitiveInputHandler(prompt string) Handler {
return HandlerFunc(func(rw *ResponseWriter, req *Request) {
SensitiveInput(rw, req, prompt)
})
}
// CertificateRequired responds to the request with the CertificateRequired
// status code.
func CertificateRequired(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusCertificateRequired, "Certificate required")
}
// CertificateNotAuthorized responds to the request with
// the CertificateNotAuthorized status code.
func CertificateNotAuthorized(rw *ResponseWriter, req *Request) {
rw.WriteHeader(StatusCertificateNotAuthorized, "Certificate not authorized")
}
// ServeMux is a Gemini request multiplexer.
// It matches the URL of each incoming request against a list of registered
// patterns and calls the handler for the pattern that most closesly matches