Skip to content

Commit

Permalink
Merge pull request #26 from SgtCoDFish/lasteffort
Browse files Browse the repository at this point in the history
add upsert, rework db, improve local dev
  • Loading branch information
SgtCoDFish authored Mar 20, 2024
2 parents 058c011 + 0c246e3 commit 080d9f0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 14 deletions.
2 changes: 2 additions & 0 deletions certificate.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ <h2>Hi, {{.Name}} &lt;{{.Email}}&gt;!</h2>
</button>
</form>

<!--
<br />
<form method="GET" action="/download">
Expand All @@ -117,6 +118,7 @@ <h2>Hi, {{.Name}} &lt;{{.Email}}&gt;!</h2>
Download PEM Private Key
</button>
</form>
-->
</div>
{{end}}

Expand Down
4 changes: 4 additions & 0 deletions guestbook/certificate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ spec:
duration: 87600h # 10 years
dnsNames:
- guestbook.print-your-cert.cert-manager.io
- readonly-guestbook.print-your-cert.cert-manager.io
ipAddresses:
- 127.0.0.1
- "::1"
issuerRef:
name: root-print-your-cert-ca-issuer
kind: Issuer
5 changes: 5 additions & 0 deletions guestbook/index-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -eu -o pipefail

curl --cacert ca.crt --cert /tmp/chain.pem --key /tmp/pkey.pem --resolve guestbook.print-your-cert.cert-manager.io:9090:127.0.0.1 https://guestbook.print-your-cert.cert-manager.io:9090/
5 changes: 5 additions & 0 deletions guestbook/index-readonly-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -eu -o pipefail

curl --cacert ca.crt --resolve readonly-guestbook.print-your-cert.cert-manager.io:9090:127.0.0.1 https://readonly-guestbook.print-your-cert.cert-manager.io:9090/
8 changes: 4 additions & 4 deletions guestbook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func allMessages(ctx context.Context, db *sql.DB, w io.Writer) ([]byte, error) {
func addMessage(ctx context.Context, db *sql.DB, email string, userAgent string, msg string) error {
timestamp := time.Now().Format(time.RFC3339Nano)

_, err := db.ExecContext(ctx, `insert into entries(email, user_agent, date, message) values($1, $2, $3, $4);`, email, userAgent, timestamp, msg)
_, err := db.ExecContext(ctx, `insert into entries(email, user_agent, date, message) values($1, $2, $3, $4) on conflict(email) do update set user_agent=excluded.user_agent,date=excluded.date,message=excluded.message;`, email, userAgent, timestamp, msg)
if err != nil {
return err
}
Expand Down Expand Up @@ -138,15 +138,15 @@ func writePage(db *sql.DB) http.Handler {

err = addMessage(r.Context(), db, email, userAgent, message)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
logger.Error("failed to add message to database", "error", err)
http.Error(w, "failed to add message to database", http.StatusBadRequest)
return
}

logger.Info("added message", "email", email, "contents", message, "user-agent", userAgent)

w.WriteHeader(http.StatusOK)
w.Write([]byte("successfully added message"))
w.Write([]byte("successfully added message, thanks for visiting the booth!\n"))
})
}

Expand Down Expand Up @@ -345,7 +345,7 @@ func createDB(ctx context.Context, path string) error {

defer db.Close()

if _, err = db.ExecContext(ctx, `create table entries(email, user_agent, date, message);`); err != nil {
if _, err = db.ExecContext(ctx, `create table entries(email TEXT UNIQUE, user_agent TEXT, date TEXT, message TEXT);`); err != nil {
return err
}

Expand Down
8 changes: 8 additions & 0 deletions guestbook/write-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

set -eu -o pipefail

curl --cacert ca.crt --cert /tmp/chain.pem --key /tmp/pkey.pem --resolve guestbook.print-your-cert.cert-manager.io:9090:127.0.0.1 https://guestbook.print-your-cert.cert-manager.io:9090/write \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "message=hello, world"
60 changes: 50 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"html/template"
"io"
"log"
"net"
"net/http"
"net/mail"
"net/url"
Expand Down Expand Up @@ -53,6 +54,7 @@ var (

guestbookURL = flag.String("guestbook-url", "https://guestbook.print-your-cert.cert-manager.io/write", "URL of the write path for the guestbook")
guestbookRootCAPath = flag.String("guestbook-ca", "guestbook/ca.crt", "Path to the CA certificate for the guestbook")
guestbookLocal = flag.Bool("guestbook-local", false, "If true, redirect guestbook requests to 127.0.0.1 for local testing while preserving the SNI header from guestbook-url")
)

const (
Expand Down Expand Up @@ -411,14 +413,18 @@ func downloadTarPage(kclient kubernetes.Interface, ns string) http.Handler {
var files = []struct {
Name string
Body []byte
Mode int64
}{
{"chain.pem", certPEM},
{"pkey.pem", keyPEM},
{"chain.pem", certPEM, 0o600},
{"pkey.pem", keyPEM, 0o600},
{"sign.sh", []byte(signSH), 0o700},
{"README.md", []byte(signREADME), 0o600},
}

for _, file := range files {
hdr := &tar.Header{
Name: file.Name,
Mode: 0600,
Mode: file.Mode,
Size: int64(len(file.Body)),
}

Expand Down Expand Up @@ -491,14 +497,30 @@ func signGuestbookPage(guestbookURL string, remoteRoots *x509.CertPool, kclient
return
}

guestbookClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{clientCertKeyPair},
RootCAs: remoteRoots,
},
transport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{clientCertKeyPair},
RootCAs: remoteRoots,
},
Timeout: 5 * time.Second,
}

if *guestbookLocal {
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
// redirect all connections to 127.0.0.1
// should only be used for dev
dialer := &net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 2 * time.Second,
}

addr = "127.0.0.1" + addr[strings.LastIndex(addr, ":"):]
return dialer.DialContext(ctx, network, addr)
}
}

guestbookClient := &http.Client{
Transport: transport,
Timeout: 5 * time.Second,
}

postValues := url.Values{}
Expand All @@ -514,6 +536,7 @@ func signGuestbookPage(guestbookURL string, remoteRoots *x509.CertPool, kclient

req.Header.Add("content-type", "application/x-www-form-urlencoded")
req.Header.Add("user-agent", "kiosk")
req.Header.Add("host", "guestbook.print-your-cert.cert-manager.io")

guestbookResponse, err := guestbookClient.Do(req)
if err != nil {
Expand Down Expand Up @@ -1070,3 +1093,20 @@ func getPublicKeyAlgorithm(algorithm x509.PublicKeyAlgorithm, key interface{}) s
}
return fmt.Sprintf("%s %s", algorithm, params)
}

const signSH = `#!/usr/bin/env bash
set -eu -o pipefail
curl --cert chain.pem --key pkey.pem https://guestbook.print-your-cert.cert-manager.io/write \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "message=I'm a star"
`

const signREADME = `Thanks for downloading your certificate from the cert-manager booth at KubeCon Paris 2024!
You can run sign.sh to sign the guestbook - feel free to customise the message!
You can fetch guestbook entries using: curl https://readonly-guestbook.print-your-cert.cert-manager.io
`

0 comments on commit 080d9f0

Please sign in to comment.