summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-03-27 22:55:22 -0600
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2024-03-27 22:55:22 -0600
commit75ba836d6072235fc7a71659f8630ab3c1b210ad (patch)
tree386b65ae6d7a4215c2f7b4944fc2f0922d162491
parentb2fa4fe9454cbc9c9c0e265e3e6065eaa8726e2f (diff)
downloadhatecomputers.club-75ba836d6072235fc7a71659f8630ab3c1b210ad.tar.gz
hatecomputers.club-75ba836d6072235fc7a71659f8630ab3c1b210ad.zip
add dns form
-rw-r--r--api/dns.go23
-rw-r--r--api/serve.go14
-rw-r--r--api/template.go19
-rw-r--r--database/dns.go40
-rw-r--r--static/css/colors.css12
-rw-r--r--static/css/form.css30
-rw-r--r--static/css/styles.css13
-rw-r--r--static/css/table.css26
-rw-r--r--templates/base.html26
-rw-r--r--templates/dns.html37
10 files changed, 214 insertions, 26 deletions
diff --git a/api/dns.go b/api/dns.go
new file mode 100644
index 0000000..3105f91
--- /dev/null
+++ b/api/dns.go
@@ -0,0 +1,23 @@
+package api
+
+import (
+ "log"
+ "net/http"
+
+ "git.hatecomputers.club/hatecomputers/hatecomputers.club/database"
+)
+
+func ListDNSRecordsContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
+ return func(success Continuation, failure Continuation) ContinuationChain {
+ dnsRecords, err := database.GetUserDNSRecords(context.DBConn, context.User.ID)
+ if err != nil {
+ log.Println(err)
+ resp.WriteHeader(http.StatusInternalServerError)
+ return failure(context, req, resp)
+ }
+
+ (*context.TemplateData)["DNSRecords"] = dnsRecords
+
+ return success(context, req, resp)
+ }
+}
diff --git a/api/serve.go b/api/serve.go
index 758a8d9..38b65b2 100644
--- a/api/serve.go
+++ b/api/serve.go
@@ -19,7 +19,8 @@ type RequestContext struct {
Id string
Start time.Time
- User *database.User
+ TemplateData *map[string]interface{}
+ User *database.User
}
type Continuation func(*RequestContext, *http.Request, http.ResponseWriter) ContinuationChain
@@ -75,12 +76,14 @@ func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server {
return &RequestContext{
DBConn: dbConn,
Args: argv,
+
+ TemplateData: &map[string]interface{}{},
}
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
requestContext := makeRequestContext()
- LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
+ LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation("home.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
})
mux.HandleFunc("GET /api/health", func(w http.ResponseWriter, r *http.Request) {
@@ -108,10 +111,15 @@ func MakeServer(argv *args.Arguments, dbConn *sql.DB) *http.Server {
LogRequestContinuation(requestContext, r, w)(LogoutContinuation, FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
})
+ mux.HandleFunc("GET /dns", func(w http.ResponseWriter, r *http.Request) {
+ requestContext := makeRequestContext()
+ LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(ListDNSRecordsContinuation, GoLoginContinuation)(TemplateContinuation("dns.html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
+ })
+
mux.HandleFunc("GET /{name}", func(w http.ResponseWriter, r *http.Request) {
requestContext := makeRequestContext()
name := r.PathValue("name")
- LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation(name+".html", nil, true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
+ LogRequestContinuation(requestContext, r, w)(VerifySessionContinuation, FailurePassingContinuation)(IdContinuation, IdContinuation)(TemplateContinuation(name+".html", true), FailurePassingContinuation)(LogExecutionTimeContinuation, LogExecutionTimeContinuation)(IdContinuation, IdContinuation)
})
return &http.Server{
diff --git a/api/template.go b/api/template.go
index a4ccfa8..eeaeb51 100644
--- a/api/template.go
+++ b/api/template.go
@@ -9,7 +9,7 @@ import (
"os"
)
-func renderTemplate(context *RequestContext, templateName string, showBaseHtml bool, data interface{}) (bytes.Buffer, error) {
+func renderTemplate(context *RequestContext, templateName string, showBaseHtml bool) (bytes.Buffer, error) {
templatePath := context.Args.TemplatePath
basePath := templatePath + "/base_empty.html"
if showBaseHtml {
@@ -22,11 +22,14 @@ func renderTemplate(context *RequestContext, templateName string, showBaseHtml b
return bytes.Buffer{}, err
}
- if data == nil {
- data = map[string]interface{}{}
+ dataPtr := context.TemplateData
+ if dataPtr == nil {
+ dataPtr = &map[string]interface{}{}
}
- if context.User != nil {
- data.(map[string]interface{})["User"] = context.User
+
+ data := *dataPtr
+ if data["User"] == nil {
+ data["User"] = context.User
}
var buffer bytes.Buffer
@@ -38,13 +41,13 @@ func renderTemplate(context *RequestContext, templateName string, showBaseHtml b
return buffer, nil
}
-func TemplateContinuation(path string, data interface{}, showBase bool) Continuation {
+func TemplateContinuation(path string, showBase bool) Continuation {
return func(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain {
return func(success Continuation, failure Continuation) ContinuationChain {
- html, err := renderTemplate(context, path, true, data)
+ html, err := renderTemplate(context, path, true)
if errors.Is(err, os.ErrNotExist) {
resp.WriteHeader(404)
- html, err = renderTemplate(context, "404.html", true, nil)
+ html, err = renderTemplate(context, "404.html", true)
if err != nil {
log.Println("error rendering 404 template", err)
resp.WriteHeader(500)
diff --git a/database/dns.go b/database/dns.go
new file mode 100644
index 0000000..17487b7
--- /dev/null
+++ b/database/dns.go
@@ -0,0 +1,40 @@
+package database
+
+import (
+ "database/sql"
+ _ "github.com/mattn/go-sqlite3"
+ "log"
+ "time"
+)
+
+type DNSRecord struct {
+ ID string
+ UserID string
+ Name string
+ Type string
+ Content string
+ TTL int
+ CreatedAt time.Time
+}
+
+func GetUserDNSRecords(db *sql.DB, userID string) ([]DNSRecord, error) {
+ log.Println("getting dns records for user", userID)
+
+ rows, err := db.Query("SELECT * FROM dns_records WHERE user_id = ?", userID)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ var records []DNSRecord
+ for rows.Next() {
+ var record DNSRecord
+ err := rows.Scan(&record.ID, &record.UserID, &record.Name, &record.Type, &record.Content, &record.TTL, &record.CreatedAt)
+ if err != nil {
+ return nil, err
+ }
+ records = append(records, record)
+ }
+
+ return records, nil
+}
diff --git a/static/css/colors.css b/static/css/colors.css
index 2535049..69e3e4b 100644
--- a/static/css/colors.css
+++ b/static/css/colors.css
@@ -1,25 +1,33 @@
:root {
--background-color-light: #f4e8e9;
+ --background-color-light-2: #f7f7f7;
--text-color-light: #333;
--link-color-light: #d291bc;
- --container-bg-light: #fff7f8;
+ --container-bg-light: #fff7f87a;
+ --border-color-light: #692fcc;
--background-color-dark: #333;
+ --background-color-dark-2: #2c2c2c;
--text-color-dark: #f4e8e9;
--link-color-dark: #b86b77;
- --container-bg-dark: #424242;
+ --container-bg-dark: #424242ea;
+ --border-color-dark: #956ade;
}
[data-theme="DARK"] {
--background-color: var(--background-color-dark);
+ --background-color-2: var(--background-color-dark-2);
--text-color: var(--text-color-dark);
--link-color: var(--link-color-dark);
--container-bg: var(--container-bg-dark);
+ --border-color: var(--border-color-dark);
}
[data-theme="LIGHT"] {
--background-color: var(--background-color-light);
+ --background-color-2: var(--background-color-light-2);
--text-color: var(--text-color-light);
--link-color: var(--link-color-light);
--container-bg: var(--container-bg-light);
+ --border-color: var(--border-color-light);
}
diff --git a/static/css/form.css b/static/css/form.css
new file mode 100644
index 0000000..4e14b68
--- /dev/null
+++ b/static/css/form.css
@@ -0,0 +1,30 @@
+form {
+ max-width: 600px;
+ padding: 1em;
+ background: var(--background-color-2);
+ border: 1px solid #ccc;
+}
+
+label {
+ display: block;
+ margin: 0 0 1em;
+ font-weight: bold;
+}
+
+input {
+ display: block;
+ width: 100%;
+ padding: 0.5em;
+ margin: 0 0 1em;
+ border: 1px solid var(--border-color);
+ background: var(--container-bg);
+}
+
+button,
+input[type="submit"] {
+ padding: 0.5em 1em;
+ background: var(--link-color);
+ color: var(--text-color);
+ border: 0;
+ cursor: pointer;
+}
diff --git a/static/css/styles.css b/static/css/styles.css
index ffc3114..b3babe7 100644
--- a/static/css/styles.css
+++ b/static/css/styles.css
@@ -1,5 +1,7 @@
@import "/static/css/colors.css";
@import "/static/css/blinky.css";
+@import "/static/css/table.css";
+@import "/static/css/form.css";
@font-face {
font-family: "ComicSans";
@@ -11,10 +13,10 @@
margin: 0;
padding: 0;
color: var(--text-color);
+ font-family: "ComicSans", sans-serif;
}
body {
- font-family: "ComicSans", sans-serif;
background-color: var(--background-color);
background-image: url("/static/img/stars.gif");
min-height: 100vh;
@@ -35,7 +37,6 @@ a:hover {
margin: auto;
background-color: var(--container-bg);
padding: 1rem;
- opacity: 0.95;
}
hr {
@@ -44,3 +45,11 @@ hr {
margin: 20px 0;
}
+
+.blinkies {
+ display: flex;
+ justify-content: left;
+ flex-wrap: wrap;
+ max-width: 900px;
+ gap: 10px 10px;
+}
diff --git a/static/css/table.css b/static/css/table.css
new file mode 100644
index 0000000..640ad83
--- /dev/null
+++ b/static/css/table.css
@@ -0,0 +1,26 @@
+table {
+ width: auto;
+ border-collapse: collapse;
+ border: 1px solid var(--border-color);
+}
+
+th,
+td {
+ padding: 12px 20px;
+ text-align: left;
+ border-bottom: 1px solid var(--border-color);
+}
+
+tbody tr:nth-child(odd) {
+ background-color: var(--link-color);
+ color: var(--text-color);
+}
+
+tbody tr {
+ transition: background-color 0.3s ease;
+}
+
+tbody tr:hover {
+ background-color: #ff47daa0;
+ color: #2a2a2a;
+}
diff --git a/templates/base.html b/templates/base.html
index a60ac55..79e0d12 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -50,6 +50,21 @@
<div class="footer">
<div>
+ {{ if .User }}
+ <a href="https://git.hatecomputers.club/{{ .User.Username }}">git.</a>
+ {{ else }}
+ <a href="https://git.hatecomputers.club">git.</a>
+ {{ end }}
+
+ <span> | </span>
+ <a href="https://mail.hatecomputers.club">e-mail.</a>
+ <span> | </span>
+ <a href="https://auth.hatecomputers.club">sso.</a>
+ </div>
+
+ <br>
+
+ <div class="blinkies">
<img width='150' height='20' src='/static/img/blinkies/hatecomputers-club.gif'>
<img width='150' height='20' src='/static/img/blinkies/autism.gif'>
<img width='150' height='20' src='/static/img/blinkies/fuckcomputers.gif'>
@@ -60,17 +75,6 @@
<img width='150' height='20' src='/static/img/blinkies/eepy.gif'>
<img width='150' height='20' src='/static/img/blinkies/loveuguys.gif'>
</div>
-
- {{ if .User }}
- <a href="https://git.hatecomputers.club/{{ .User.Username }}">git.</a>
- {{ else }}
- <a href="https://git.hatecomputers.club">git.</a>
- {{ end }}
-
- <span> | </span>
- <a href="https://mail.hatecomputers.club">e-mail.</a>
- <span> | </span>
- <a href="https://auth.hatecomputers.club">sso.</a>
</div>
</div>
diff --git a/templates/dns.html b/templates/dns.html
new file mode 100644
index 0000000..0a40cab
--- /dev/null
+++ b/templates/dns.html
@@ -0,0 +1,37 @@
+{{ define "content" }}
+ <table>
+ <tr>
+ <th>Type</th>
+ <th>Name</th>
+ <th>Content</th>
+ <th>TTL</th>
+ </tr>
+ {{ if (eq (len .DNSRecords) 0) }}
+ <tr>
+ <td colspan="4"><span class="blinky">No DNS records found</span></td>
+ </tr>
+ {{ end }}
+ {{ range $record := .DNSRecords }}
+ <tr>
+ <td>{{ $record.Type }}</td>
+ <td>{{ $record.Name }}</td>
+ <td>{{ $record.Content }}</td>
+ <td>{{ $record.TTL }}</td>
+ </tr>
+ {{ end }}
+ </table>
+ <br>
+ <form method="POST" action="/dns">
+ <h2>Add DNS Records</h2>
+ <hr>
+ <label for="type">Type</label>
+ <input type="text" name="type" placeholder="CNAME" required />
+ <label for="name">Name</label>
+ <input type="text" name="name" placeholder="{{ .User.Username }}" required />
+ <label for="content">Content</label>
+ <input type="text" name="content" placeholder="{{ .User.Username }}.dev" required />
+ <label for="ttl">TTL</label>
+ <input type="text" name="ttl" placeholder="43200" required />
+ <input type="submit" value="Add" />
+ </form>
+{{ end }}