feat: linklist
This commit is contained in:
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() {
|
||||||
|
42
cmd/bs1in/link.go
Normal file
42
cmd/bs1in/link.go
Normal file
@ -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"`
|
||||||
|
@ -237,4 +237,33 @@ nav > *:hover {
|
|||||||
position: relative;
|
position: relative;
|
||||||
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;
|
||||||
|
}
|
||||||
|
37
web/static/js/linklist.js
Normal file
37
web/static/js/linklist.js
Normal file
@ -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>
|
||||||
|
33
web/templates/linklist.html
Normal file
33
web/templates/linklist.html
Normal file
@ -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…
x
Reference in New Issue
Block a user