diff --git a/cmd/bs1in/bs1in.go b/cmd/bs1in/bs1in.go index f51a920..1555169 100644 --- a/cmd/bs1in/bs1in.go +++ b/cmd/bs1in/bs1in.go @@ -4,22 +4,28 @@ package main import ( + "encoding/json" "fmt" "html/template" "path" + "strings" "log" "net/http" + + "go.mongodb.org/mongo-driver/bson/primitive" ) func main() { http.HandleFunc("/login", handleLogin) http.HandleFunc("/register", handleRegister) - http.HandleFunc("/logout", validateSession(handleLogout, "")) http.HandleFunc("/", validateSession(handleIndex, "")) http.HandleFunc("/database", validateSession(handleDatabase, "")) + http.HandleFunc("/linklist", validateSession(handleLinkList, "")) http.HandleFunc("/admin_panel", validateSession(handleAdminPanel, "admin")) + + http.HandleFunc("/logout", validateSession(handleLogout, "")) // provide the inc directory to the useragent http.HandleFunc("/static/", validateSession(handleStatic, "")) // 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) } +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) { if r.Method == http.MethodGet { t, _ := getTemplate("layouts/base.html", "soon.html", "header.html") diff --git a/cmd/bs1in/database.go b/cmd/bs1in/database.go index 4d8eae7..947269b 100644 --- a/cmd/bs1in/database.go +++ b/cmd/bs1in/database.go @@ -19,6 +19,7 @@ import ( var client mongo.Client var colUsers *mongo.Collection +var colLinks *mongo.Collection var mongoCtx context.Context var mariaDB *sql.DB @@ -45,6 +46,7 @@ func openMongoDBConnection() { } colUsers = client.Database("bs1in").Collection("users") + colLinks = client.Database("bs1in").Collection("links") } func openMariaDBConnection() { diff --git a/cmd/bs1in/link.go b/cmd/bs1in/link.go new file mode 100644 index 0000000..1b90601 --- /dev/null +++ b/cmd/bs1in/link.go @@ -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 +} diff --git a/cmd/bs1in/user.go b/cmd/bs1in/user.go index 13059ed..a0982b5 100644 --- a/cmd/bs1in/user.go +++ b/cmd/bs1in/user.go @@ -13,7 +13,7 @@ import ( type User struct { ID primitive.ObjectID `bson:"_id"` UID string `bson:"uid"` - Mail string `bson: mail` + Mail string `bson:"mail"` Pass string `bson:"pass"` CurrSession Session `bson:"curr_session"` Role string `bson:"role"` diff --git a/web/static/css/bs1in.css b/web/static/css/bs1in.css index d84a530..b2fc9d0 100644 --- a/web/static/css/bs1in.css +++ b/web/static/css/bs1in.css @@ -237,4 +237,33 @@ nav > *:hover { position: relative; width: 80%; left: 10%; -} \ No newline at end of file +} + + +/******************* 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; +} diff --git a/web/static/js/linklist.js b/web/static/js/linklist.js new file mode 100644 index 0000000..8bb69d1 --- /dev/null +++ b/web/static/js/linklist.js @@ -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"); + }); +}); \ No newline at end of file diff --git a/web/templates/header.html b/web/templates/header.html index c1742ed..323874e 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -2,7 +2,8 @@
diff --git a/web/templates/linklist.html b/web/templates/linklist.html new file mode 100644 index 0000000..03d64e5 --- /dev/null +++ b/web/templates/linklist.html @@ -0,0 +1,33 @@ +{{define "body"}} +
+ + {{range .Links}} + + + {{- if eq $.User.Role "admin"}} + + {{end}} + + {{end}} + + {{- if eq .User.Role "admin"}} +
+ + + + + +
+ + {{end}} +
+{{end}} + +{{define "scripts"}} + + +{{end}} \ No newline at end of file