Golang bot for managing discord verifications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

238 lines
6.8 KiB

package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
var (
store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
toks = make(map[string]Tokens)
)
func topWrapper(r *http.Request) string {
defer log.PanicSafe()
headerTemplate, err := os.ReadFile("./static/header.tpl")
if err != nil {
log.LogError(fmt.Sprintf("Unable to open header template: ```%+v```", err))
return ""
}
header := string(headerTemplate)
login := "Login"
loggedIn, user := detectUser(r, "topWrapper")
if loggedIn {
login = fmt.Sprintf("Logout %s", user)
}
header = strings.Replace(header, "$LOGIN", login, -1)
return header
}
func bodyWrapper(r *http.Request, template string) string {
defer log.PanicSafe()
bodyTemplate, err := os.ReadFile(fmt.Sprintf("./static/%+v.tpl", template))
if err != nil {
log.LogError(fmt.Sprintf("Attempt to load %s.tpl failed. ```%+v```", template, err))
return bodyWrapper(r, "404")
}
return string(bodyTemplate)
}
func pageBuilder(r *http.Request, pageName string) string {
defer log.PanicSafe()
pageCode := topWrapper(r)
pageCode += bodyWrapper(r, pageName)
return pageCode
}
func greetUser(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
log.LogInfo(fmt.Sprintf("%s called greetUser", getSessionIdentifier(r)))
loggedIn, _ := detectUser(r, "Homepage")
if loggedIn {
bodyTemplate, _ := os.ReadFile("./static/index.html")
fmt.Fprint(w, string(bodyTemplate))
} else {
fmt.Fprint(w, pageBuilder(r, "home"))
}
}
func passPage(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
log.LogInfo(fmt.Sprintf("%s called passPage", getSessionIdentifier(r)))
fmt.Fprint(w, pageBuilder(r, "pass"))
}
func loginPage(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
log.LogInfo(fmt.Sprintf("%s called loginPage", getSessionIdentifier(r)))
session, err := store.Get(r, "2fa")
if err != nil {
log.LogWarn("Unable to open 2fa session in loginpage")
}
loggedIn, _ := detectUser(r, "loginPage")
if loggedIn {
session.Values["username"] = nil
err = session.Save(r, w)
if err != nil {
log.LogWarn("Error logging out from loginPage()")
}
fmt.Fprint(w, pageBuilder(r, "home"))
return
}
fmt.Fprint(w, pageBuilder(r, "login"))
}
func notFoundPage(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
go log.LogWarn(fmt.Sprintf("%s triggered notFoundPage", getSessionIdentifier(r)))
fmt.Fprint(w, topWrapper(r))
fmt.Fprint(w, card("Oops! That Page Was Not found.",
"Sorry, a 404 error has occured. The requested page not found! <br><br>"+
"<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/t3otBjVZzT0\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>",
"<div class=\"error-actions\"><a href=\"/\" class=\"btn btn-primary btn-lg\"><span class=\"glyphicon glyphicon-home\"></span>Take Me Home </a> <a href=\"mailto://rudi@nmare.net\" class=\"btn btn-default btn-lg\"><span class=\"glyphicon glyphicon-envelope\"></span> Contact Support </a></div>"))
}
func card(title string, content string, footer string) string {
defer log.PanicSafe()
cardTemplate, err := os.ReadFile("./static/card.tpl")
if err != nil {
log.LogError("Unable to open card template")
return ""
}
cardString := string(cardTemplate)
cardString = strings.Replace(cardString, "$TITLE", title, -1)
cardString = strings.Replace(cardString, "$CONTENT", content, -1)
cardString = strings.Replace(cardString, "$FOOTER", footer, -1)
return cardString
}
func getPending(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
loggedIn, _ := detectUser(r, "getPending")
if loggedIn {
pending, err := json.Marshal(config.Verifications)
if err != nil {
log.LogErrorType(err)
notFoundPage(w, r)
}
fmt.Fprint(w, string(pending))
} else {
notFoundPage(w, r)
}
}
func getConfig(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
loggedIn, _ := detectUser(r, "getConfig")
if loggedIn {
pending, err := json.Marshal(config)
if err != nil {
log.LogErrorType(err)
notFoundPage(w, r)
}
fmt.Fprint(w, string(pending))
} else {
notFoundPage(w, r)
}
}
func getProbations(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
loggedIn, _ := detectUser(r, "getProbations")
if loggedIn {
pending, err := json.Marshal(config.Probations)
if err != nil {
log.LogErrorType(err)
notFoundPage(w, r)
}
fmt.Fprint(w, string(pending))
} else {
notFoundPage(w, r)
}
}
func getVerifications(w http.ResponseWriter, r *http.Request) {
defer log.PanicSafe()
loggedIn, _ := detectUser(r, "getVerifications")
if !loggedIn {
notFoundPage(w, r)
return
}
var files []string
root := "./verifications/"
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
files = append(files, path)
return nil
})
if err != nil {
log.LogErrorType(err)
}
var v []Verification
for _, file := range files {
info := strings.Split(file, "-")
if len(info) < 2 {
continue
}
var ver Verification
ver.UserID = strings.Replace(info[0], "verifications/", "", -1)
ver.Username = info[1]
ver.Photo = file
fileStat, _ := os.Stat(file)
ver.Closed = fileStat.ModTime()
v = append(v, ver)
}
verifications, err := json.Marshal(v)
if err != nil {
log.LogErrorType(err)
}
fmt.Fprint(w, string(verifications))
}
func getUser(w http.ResponseWriter, r *http.Request) {
loggedIn, _ := detectUser(r, "getVerifications")
if !loggedIn {
notFoundPage(w, r)
return
}
vars := mux.Vars(r)
username := vars["userID"]
if len(username) == 0 {
username = r.FormValue("userID")
}
m, err := dg.GuildMember(config.GuildID, username)
if err != nil {
log.LogErrorType(err)
}
ret, err := json.Marshal(m)
if err != nil {
log.LogErrorType(err)
}
fmt.Fprint(w, string(ret))
}
func runWeb() {
defer log.PanicSafe()
router := mux.NewRouter().StrictSlash(true)
log.LogInfo("Adding HandleFuncs to router")
router.NotFoundHandler = http.HandlerFunc(notFoundPage)
router.HandleFunc("/pass", passPage)
router.HandleFunc("/login", loginPage)
router.HandleFunc("/api/login", tryLogin)
router.HandleFunc("/api/config", getConfig)
router.HandleFunc("/api/pending", getPending)
router.HandleFunc("/api/verifications", getVerifications)
router.HandleFunc("/api/probations", getProbations)
router.HandleFunc("/api/passreq", reqPass)
router.HandleFunc("/api/user", getUser)
router.HandleFunc("/", greetUser)
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
router.PathPrefix("/verifications/").Handler(http.StripPrefix("/verifications/", http.FileServer(http.Dir("./verifications"))))
log.LogInfo("Starting server")
log.LogErrorType(http.ListenAndServe(":8080", router))
}