the shrimplest admin api you've ever seen
Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
parent
1cbcece3d2
commit
c5a2491627
20
api/api.go
Normal file
20
api/api.go
Normal 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
43
api/v1/admin/admin.go
Normal 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
43
main.go
|
@ -1,20 +1,21 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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/html"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
"github.com/gomarkdown/markdown"
|
||||
"github.com/gomarkdown/markdown/html"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
)
|
||||
|
||||
const PORT int = 8080
|
||||
|
@ -94,6 +95,14 @@ func handle_request(writer http.ResponseWriter, req *http.Request) {
|
|||
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)
|
||||
}(writer, req)
|
||||
|
||||
|
@ -138,6 +147,16 @@ func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *
|
|||
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 {
|
||||
filename := "public/" + req.URL.Path[1:]
|
||||
|
||||
|
|
152
public/style/admin.css
Normal file
152
public/style/admin.css
Normal 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
20
views/admin.html
Normal 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}}
|
Loading…
Reference in a new issue