the shrimplest admin api you've ever seen

Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
ari melody 2024-04-16 22:58:39 +01:00
parent 1cbcece3d2
commit c5a2491627
5 changed files with 266 additions and 12 deletions

20
api/api.go Normal file
View file

@ -0,0 +1,20 @@
package api
import (
"net/http"
"html/template"
"arimelody.me/arimelody.me/api/v1/admin"
)
func Handle(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
code := 404;
if req.URL.Path == "/api/v1/admin/login" {
code = admin.HandleLogin(writer, req, root)
}
if code == 404 {
writer.Write([]byte("404 not found"))
}
return code;
}

43
api/v1/admin/admin.go Normal file
View file

@ -0,0 +1,43 @@
package admin
import (
"fmt"
"html/template"
"io"
"net/http"
)
type (
State struct {
Token string
}
)
func CreateState() *State {
return &State{
Token: "you are the WINRAR!!",
}
}
func HandleLogin(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if req.Method != "POST" {
return 404;
}
body, err := io.ReadAll(req.Body)
if err != nil {
fmt.Printf("failed to parse request body!\n");
return 500;
}
if string(body) != "super epic mega gaming password" {
return 400;
}
state := CreateState();
writer.WriteHeader(200);
writer.Write([]byte(state.Token))
return 200;
}

43
main.go
View file

@ -1,20 +1,21 @@
package main package main
import ( import (
"fmt" "fmt"
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"arimelody.me/arimelody.me/api/v1/music" "arimelody.me/arimelody.me/api"
"arimelody.me/arimelody.me/api/v1/music"
"github.com/gomarkdown/markdown" "github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html" "github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser" "github.com/gomarkdown/markdown/parser"
) )
const PORT int = 8080 const PORT int = 8080
@ -94,6 +95,14 @@ func handle_request(writer http.ResponseWriter, req *http.Request) {
return music_gateway_handler(writer, req, root) return music_gateway_handler(writer, req, root)
} }
if strings.HasPrefix(uri, "/admin") {
return admin_handler(writer, req, root)
}
if strings.HasPrefix(uri, "/api") {
return api.Handle(writer, req, root)
}
return static_handler(writer, req, root) return static_handler(writer, req, root)
}(writer, req) }(writer, req)
@ -138,6 +147,16 @@ func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *
return 200 return 200
} }
func admin_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
admin_template := template.Must(root.ParseFiles("views/admin.html"))
err := admin_template.Execute(writer, nil)
if err != nil {
http.Error(writer, err.Error(), http.StatusInternalServerError)
return 500
}
return 200
}
func static_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int { func static_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
filename := "public/" + req.URL.Path[1:] filename := "public/" + req.URL.Path[1:]

152
public/style/admin.css Normal file
View file

@ -0,0 +1,152 @@
@import url("/style/main.css");
main {
width: min(calc(100% - 4rem), 720px);
min-height: calc(100vh - 10.3rem);
margin: 0 auto 2rem auto;
padding-top: 4rem;
}
main h1 {
line-height: 3rem;
color: var(--primary);
}
main h2 {
color: var(--secondary);
}
main h3 {
color: var(--tertiary);
}
div#me_irl {
width: fit-content;
height: fit-content;
border: 2px solid white;
}
div#me_irl img {
display: block;
}
div#me_irl::before {
content: "";
position: absolute;
width: 104px;
height: 104px;
transform: translate(2px, 2px);
background-image: linear-gradient(to top right,
var(--primary),
var(--secondary));
z-index: -1;
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
small,
blockquote {
transition: background-color 0.1s;
}
h1 a,
h2 a,
h3 a,
h4 a,
h5 a,
h6 a {
color: inherit;
}
h1 a:hover,
h2 a:hover,
h3 a:hover,
h4 a:hover,
h5 a:hover,
h6 a:hover {
text-decoration: none;
}
main h1:hover,
main h2:hover,
main h3:hover,
main h4:hover,
main h5:hover,
main h6:hover,
main p:hover,
main small:hover,
main blockquote:hover {
background-color: #fff1;
}
blockquote {
margin: 1rem 0;
padding: 0 2.5rem;
}
hr {
text-align: center;
line-height: 0px;
border-width: 1px 0 0 0;
border-color: #888f;
margin: 1.5em 0;
overflow: visible;
}
ul.links {
display: flex;
gap: 1em .5em;
flex-wrap: wrap;
}
ul.links li {
list-style: none;
}
ul.links li a {
padding: .2em .5em;
border: 1px solid var(--links);
color: var(--links);
border-radius: 2px;
background-color: transparent;
transition-property: color, border-color, background-color;
transition-duration: .2s;
animation-delay: 0s;
animation: list-item-fadein .2s forwards;
opacity: 0;
}
ul.links li a:hover {
color: #eee;
border-color: #eee;
background-color: var(--links) !important;
text-decoration: none;
box-shadow: 0 0 1em var(--links);
}
div#web-buttons {
margin: 2rem 0;
}
#web-buttons a {
text-decoration: none;
}
#web-buttons img {
image-rendering: auto;
image-rendering: crisp-edges;
image-rendering: pixelated;
}
#web-buttons img:hover {
margin: -1px;
border: 1px solid #eee;
transform: translate(-2px, -2px);
box-shadow: 1px 1px 0 #eee, 2px 2px 0 #eee;
}

20
views/admin.html Normal file
View file

@ -0,0 +1,20 @@
{{define "head"}}
<title>admin - ari melody 💫</title>
<link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/style/admin.css">
{{end}}
{{define "content"}}
<main>
<script type="module" src="/script/admin.js" defer></script>
<h1>
# admin panel
</h1>
<p>
bappity boopity
</p>
</main>
{{end}}