feat: linklist

master
phga 3 years ago
parent 0f6ebe1e58
commit 6af8b87dd4

@ -4,22 +4,28 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"path" "path"
"strings"
"log" "log"
"net/http" "net/http"
"go.mongodb.org/mongo-driver/bson/primitive"
) )
func main() { func main() {
http.HandleFunc("/login", handleLogin) http.HandleFunc("/login", handleLogin)
http.HandleFunc("/register", handleRegister) http.HandleFunc("/register", handleRegister)
http.HandleFunc("/logout", validateSession(handleLogout, ""))
http.HandleFunc("/", validateSession(handleIndex, "")) http.HandleFunc("/", validateSession(handleIndex, ""))
http.HandleFunc("/database", validateSession(handleDatabase, "")) http.HandleFunc("/database", validateSession(handleDatabase, ""))
http.HandleFunc("/linklist", validateSession(handleLinkList, ""))
http.HandleFunc("/admin_panel", validateSession(handleAdminPanel, "admin")) http.HandleFunc("/admin_panel", validateSession(handleAdminPanel, "admin"))
http.HandleFunc("/logout", validateSession(handleLogout, ""))
// provide the inc directory to the useragent // provide the inc directory to the useragent
http.HandleFunc("/static/", validateSession(handleStatic, "")) http.HandleFunc("/static/", validateSession(handleStatic, ""))
// listen on port 8080 (I use nginx to proxy this local server) // listen on port 8080 (I use nginx to proxy this local server)
@ -47,6 +53,58 @@ func handleIndex(w http.ResponseWriter, r *http.Request) {
t.Execute(w, td) t.Execute(w, td)
} }
func handleLinkList(w http.ResponseWriter, r *http.Request) {
currUser := r.Context().Value(currUserKey).(User)
if r.Method == http.MethodGet {
t, _ := getTemplate("layouts/base.html", "linklist.html", "header.html")
linkList := getLinksFromDatabase()
// Put linklist into template
td := TmplData{currUser, struct {
User User
Links []Link
}{currUser, linkList}}
t.Execute(w, td)
} else if r.Method == http.MethodPost {
// If not admin -> do nothing
if currUser.Role != "admin" {
w.WriteHeader(http.StatusForbidden)
return
}
if err := r.ParseForm(); err != nil {
log.Fatal(err)
}
url := r.PostForm.Get("url")
desc := r.PostForm.Get("description")
if !strings.HasPrefix(url, "http://") ||
!strings.HasPrefix(url, "https://") {
url = "https://" + url
}
if addLinkToDatabase(Link{primitive.NewObjectID(), url, desc}) {
w.Header().Set("Location", "/linklist")
w.WriteHeader(http.StatusFound)
}
} else if r.Method == http.MethodDelete {
// If not admin -> do nothing
if currUser.Role != "admin" {
w.WriteHeader(http.StatusForbidden)
return
}
d := json.NewDecoder(r.Body)
var link Link
err := d.Decode(&link)
if err != nil {
log.Println(err, r.Body)
}
if !deleteLinkFromDatabase(link.ID) {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
}
func handleAdminPanel(w http.ResponseWriter, r *http.Request) { func handleAdminPanel(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet { if r.Method == http.MethodGet {
t, _ := getTemplate("layouts/base.html", "soon.html", "header.html") t, _ := getTemplate("layouts/base.html", "soon.html", "header.html")

@ -19,6 +19,7 @@ import (
var client mongo.Client var client mongo.Client
var colUsers *mongo.Collection var colUsers *mongo.Collection
var colLinks *mongo.Collection
var mongoCtx context.Context var mongoCtx context.Context
var mariaDB *sql.DB var mariaDB *sql.DB
@ -45,6 +46,7 @@ func openMongoDBConnection() {
} }
colUsers = client.Database("bs1in").Collection("users") colUsers = client.Database("bs1in").Collection("users")
colLinks = client.Database("bs1in").Collection("links")
} }
func openMariaDBConnection() { func openMariaDBConnection() {

@ -0,0 +1,42 @@
package main
import (
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Link struct {
ID primitive.ObjectID `bson:"_id" json:"id"`
Url string `bson:"url"`
Description string `bson:"description"`
}
func addLinkToDatabase(l Link) bool {
_, err := colLinks.InsertOne(mongoCtx, l)
if err != nil {
log.Println("Could not add new link to database: ", err)
return false
}
return true
}
func deleteLinkFromDatabase(id primitive.ObjectID) bool {
_, err := colLinks.DeleteOne(mongoCtx, bson.M{"_id": id})
if err != nil {
log.Println("Could not remove link from database: ", err)
return false
}
return true
}
func getLinksFromDatabase() (links []Link) {
cursor, err := colLinks.Find(mongoCtx, bson.M{})
if err != nil {
log.Println("Could not remove link from database: ", err)
return nil
}
cursor.All(mongoCtx, &links)
return
}

@ -13,7 +13,7 @@ import (
type User struct { type User struct {
ID primitive.ObjectID `bson:"_id"` ID primitive.ObjectID `bson:"_id"`
UID string `bson:"uid"` UID string `bson:"uid"`
Mail string `bson: mail` Mail string `bson:"mail"`
Pass string `bson:"pass"` Pass string `bson:"pass"`
CurrSession Session `bson:"curr_session"` CurrSession Session `bson:"curr_session"`
Role string `bson:"role"` Role string `bson:"role"`

@ -238,3 +238,32 @@ nav > *:hover {
width: 80%; width: 80%;
left: 10%; left: 10%;
} }
/******************* Linklist *******************/
#linklist {
width: 100%;
font-weight: bold;
font-size: 1.4em;
}
#linklist a {
text-decoration: none;
color: var(--black);
display: inline-block;
}
#linklist td:last-child {
width: 30px;
}
#linklist button {
width: 30px;
height: 30px;
padding: 0;
line-height: 30px;
font-size: 0.7em;
color: var(--red);
background: none;
}

@ -0,0 +1,37 @@
let ll = document.getElementById("linklist");
let infoBox = document.getElementById("general-info");
ll.addEventListener("click", e => {
let rbtn = e.target;
if (!rbtn.classList.contains("btn-delete")) {
return;
}
e.preventDefault();
let row = e.target.parentNode.parentNode;
let link_id = row.children[0].dataset.id;
toggleDisabled(rbtn, "on");
fetch("/linklist", {
method: "DELETE",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({id: link_id})
}).then(res => {
if (res.status == 200) {
row.remove();
} else {
setInfo(infoBox, "Failure", "red", "grey1");
toggleHidden(infoBox, "off");
setTimeout(() => {
toggleHidden(infoBox, "on");
}, 2000);
}
toggleDisabled(rbtn, "off");
});
});

@ -2,7 +2,8 @@
<header> <header>
<nav> <nav>
<a href="/">home</a> <a href="/">home</a>
<a target="_blank" href="https://db.eeez.de">db.eeez.de</a> <!-- <a target="_blank" href="https://db.eeez.de">db.eeez.de</a> -->
<a href="/linklist">linklist</a>
<a href="/admin_panel">admin</a> <a href="/admin_panel">admin</a>
<a href="/logout">logout</a> <a href="/logout">logout</a>
</nav> </nav>

@ -0,0 +1,33 @@
{{define "body"}}
<section id="wrapper">
<table id="linklist">
{{range .Links}}
<tr>
<td data-id="{{UnwrapOID .ID}}">
<a target="_blank" href="{{.Url}}">{{.Description}}</a>
</td>
{{- if eq $.User.Role "admin"}}
<td>
<button class="btn-delete"></button>
</td>
{{end}}
</tr>
{{end}}
</table>
{{- if eq .User.Role "admin"}}
<form action="/linklist" method="post">
<label for="inp-url">URL</label>
<input id="inp-url" name="url" type="text" value=""/>
<label for="inp-desc">Description</label>
<input id="inp-desc" name="description" type="text" value=""/>
<button>Create</button>
</form>
<div class="hidden" id="general-info"></div>
{{end}}
</section>
{{end}}
{{define "scripts"}}
<script src="/static/js/helper.js"></script>
<script src="/static/js/linklist.js"></script>
{{end}}
Loading…
Cancel
Save