Add Client.GetInput field

This commit is contained in:
Adnan Maolood
2020-10-27 23:35:22 -04:00
parent d1dcf070ff
commit 4c5167f590
6 changed files with 61 additions and 60 deletions

View File

@@ -7,7 +7,7 @@ import (
"fmt"
"log"
gmi "git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini"
)
type user struct {
@@ -33,15 +33,14 @@ var (
)
func main() {
var mux gmi.ServeMux
mux.HandleFunc("/", welcome)
mux.HandleFunc("/login", login)
mux.HandleFunc("/login/password", loginPassword)
var mux gemini.ServeMux
mux.HandleFunc("/", login)
mux.HandleFunc("/password", loginPassword)
mux.HandleFunc("/profile", profile)
mux.HandleFunc("/admin", admin)
mux.HandleFunc("/logout", logout)
var server gmi.Server
var server gemini.Server
if err := server.CertificateStore.Load("/var/lib/gemini/certs"); err != nil {
log.Fatal(err)
}
@@ -53,74 +52,69 @@ func main() {
}
func getSession(crt *x509.Certificate) (*session, bool) {
fingerprint := gmi.Fingerprint(crt)
fingerprint := gemini.Fingerprint(crt)
session, ok := sessions[fingerprint]
return session, ok
}
func welcome(w *gmi.ResponseWriter, r *gmi.Request) {
fmt.Fprintln(w, "Welcome to this example.")
fmt.Fprintln(w, "=> /login Login")
}
func login(w *gmi.ResponseWriter, r *gmi.Request) {
cert, ok := gmi.Certificate(w, r)
func login(w *gemini.ResponseWriter, r *gemini.Request) {
cert, ok := gemini.Certificate(w, r)
if !ok {
return
}
username, ok := gmi.Input(w, r, "Username")
username, ok := gemini.Input(w, r, "Username")
if !ok {
return
}
fingerprint := gmi.Fingerprint(cert)
fingerprint := gemini.Fingerprint(cert)
sessions[fingerprint] = &session{
username: username,
}
gmi.Redirect(w, "/login/password")
gemini.Redirect(w, "/password")
}
func loginPassword(w *gmi.ResponseWriter, r *gmi.Request) {
cert, ok := gmi.Certificate(w, r)
func loginPassword(w *gemini.ResponseWriter, r *gemini.Request) {
cert, ok := gemini.Certificate(w, r)
if !ok {
return
}
session, ok := getSession(cert)
if !ok {
w.WriteStatus(gmi.StatusCertificateNotAuthorized)
w.WriteStatus(gemini.StatusCertificateNotAuthorized)
return
}
password, ok := gmi.SensitiveInput(w, r, "Password")
password, ok := gemini.SensitiveInput(w, r, "Password")
if !ok {
return
}
expected := logins[session.username].password
if password == expected {
session.authorized = true
gmi.Redirect(w, "/profile")
gemini.Redirect(w, "/profile")
} else {
gmi.SensitiveInput(w, r, "Wrong password. Try again")
gemini.SensitiveInput(w, r, "Wrong password. Try again")
}
}
func logout(w *gmi.ResponseWriter, r *gmi.Request) {
cert, ok := gmi.Certificate(w, r)
func logout(w *gemini.ResponseWriter, r *gemini.Request) {
cert, ok := gemini.Certificate(w, r)
if !ok {
return
}
fingerprint := gmi.Fingerprint(cert)
fingerprint := gemini.Fingerprint(cert)
delete(sessions, fingerprint)
fmt.Fprintln(w, "Successfully logged out.")
}
func profile(w *gmi.ResponseWriter, r *gmi.Request) {
cert, ok := gmi.Certificate(w, r)
func profile(w *gemini.ResponseWriter, r *gemini.Request) {
cert, ok := gemini.Certificate(w, r)
if !ok {
return
}
session, ok := getSession(cert)
if !ok {
w.WriteStatus(gmi.StatusCertificateNotAuthorized)
w.WriteStatus(gemini.StatusCertificateNotAuthorized)
return
}
user := logins[session.username]
@@ -129,19 +123,19 @@ func profile(w *gmi.ResponseWriter, r *gmi.Request) {
fmt.Fprintln(w, "=> /logout Logout")
}
func admin(w *gmi.ResponseWriter, r *gmi.Request) {
cert, ok := gmi.Certificate(w, r)
func admin(w *gemini.ResponseWriter, r *gemini.Request) {
cert, ok := gemini.Certificate(w, r)
if !ok {
return
}
session, ok := getSession(cert)
if !ok {
w.WriteStatus(gmi.StatusCertificateNotAuthorized)
w.WriteStatus(gemini.StatusCertificateNotAuthorized)
return
}
user := logins[session.username]
if !user.admin {
w.WriteStatus(gmi.StatusCertificateNotAuthorized)
w.WriteStatus(gemini.StatusCertificateNotAuthorized)
return
}
fmt.Fprintln(w, "Welcome to the admin portal.")

View File

@@ -11,13 +11,13 @@ import (
"os"
"time"
gmi "git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini"
)
func main() {
host := "localhost"
duration := 365 * 24 * time.Hour
cert, err := gmi.NewCertificate(host, duration)
cert, err := gemini.NewCertificate(host, duration)
if err != nil {
log.Fatal(err)
}

View File

@@ -76,13 +76,7 @@ func sendRequest(req *gemini.Request) error {
return err
}
switch resp.Status.Class() {
case gemini.StatusClassInput:
fmt.Printf("%s: ", resp.Meta)
scanner.Scan()
req.URL.RawQuery = url.QueryEscape(scanner.Text())
return sendRequest(req)
case gemini.StatusClassSuccess:
if resp.Status.Class() == gemini.StatusClassSuccess {
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
@@ -90,20 +84,8 @@ func sendRequest(req *gemini.Request) error {
}
fmt.Print(string(body))
return nil
case gemini.StatusClassRedirect:
// This should not happen unless CheckRedirect returns false.
return fmt.Errorf("Failed to redirect to %s", resp.Meta)
case gemini.StatusClassTemporaryFailure:
return fmt.Errorf("Temporary failure: %s", resp.Meta)
case gemini.StatusClassPermanentFailure:
return fmt.Errorf("Permanent failure: %s", resp.Meta)
case gemini.StatusClassCertificateRequired:
// Note that this should not happen unless the server responds with
// CertificateRequired even after we send a certificate.
// CertificateNotAuthorized and CertificateNotValid are handled here.
return fmt.Errorf("Certificate required: %s", resp.Meta)
}
panic("unreachable")
return fmt.Errorf("request failed: %d %s: %s", resp.Status, resp.Status.Message(), resp.Meta)
}
type trust int