30 Commits

Author SHA1 Message Date
midou 79f5117e63 Status OK
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-27 15:41:14 +01:00
midou 0cdcadb27b Uuuh yeah Status OK is better here.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-24 16:30:27 +01:00
midou fcf66afb14 Quick fix + Modularity + New form option.
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-24 16:26:47 +01:00
midou 6bdbf3b83d Make it compatible with the previous version.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 19:16:57 +01:00
midou 1c2e6e3da9 Fix everything odyssey pointed out.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 17:44:37 +01:00
midou 65d35747fc Fix Some more stuff, disabling form actually works now.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 17:18:14 +01:00
midou af39a52971 Ok so, pages don't get disabled, but they don't show up! Half working.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 01:43:17 +01:00
midou 16ea5c3138 Fix the go error.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 00:40:46 +01:00
midou 0beb8a33de Did I forget the image? Maybe I did.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 00:37:34 +01:00
midou 3abdbde812 Add dev to docker (there has to be a way to improve this!) 2022-09-18 00:34:45 +01:00
midou bfdc165346 I'm stupid.
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-18 00:26:10 +01:00
midou 64a39ac5e5 fuck this was the solution
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 23:24:32 +01:00
midou 950d65ca59 huh?
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 23:23:39 +01:00
midou 65634751b6 fix
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 23:20:23 +01:00
midou 7542cfba4a Meanwhile on gitea
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 23:16:52 +01:00
midou 9a504d1638 Partial working form and announcements settings.
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 23:12:06 +01:00
midou e614ab79fa Use viper instead of the clusterfuck of json i was trying to use.
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 22:33:44 +01:00
midou 41209f3ee3 ignore options.
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 22:18:21 +01:00
Odyssey 977136d9c2 h
Signed-off-by: Odyssey <odyssey346@disroot.org>
2022-09-17 23:08:33 +02:00
Odyssey b05c48cfbb no options.sjon
Signed-off-by: Odyssey <odyssey346@disroot.org>
2022-09-17 23:04:03 +02:00
Odyssey 11a792d96c improve grammar here
Signed-off-by: Odyssey <odyssey346@disroot.org>
2022-09-17 23:03:47 +02:00
midou 427bec5081 make it better
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 21:55:50 +01:00
midou dc69cc447d Initial work
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-17 21:50:55 +01:00
midou c5b3c2bd98 Initial work. 2022-09-17 21:50:46 +01:00
Midou36O e8d8b9b096 Update docker.yml
ci/woodpecker/push/woodpecker Pipeline failed
2022-09-15 17:37:33 +00:00
Midou36O a18f76d206 Merge pull request #2 from ProjectSegfault/form-update
WIP: Forms UI rework.
2022-09-14 13:35:17 +00:00
midou 50b058c1d2 Finished. 2022-09-14 14:32:56 +01:00
midou fc5fc6a91d Partial work. 2022-09-14 10:17:18 +01:00
midou cbd31e8893 fuck it, commit to main. 2022-09-13 14:47:10 +01:00
Midou36O f0ed8fbc39 Merge pull request #1 from ProjectSegfault/optional
remove the required tag
2022-09-13 13:36:38 +00:00
15 changed files with 249 additions and 40 deletions
+1 -1
View File
@@ -26,4 +26,4 @@ jobs:
uses: docker/build-push-action@v3 uses: docker/build-push-action@v3
with: with:
push: true push: true
tags: projectsegfault/segfautils:latest tags: realprojectsegfault/segfautils:latest
+2
View File
@@ -0,0 +1,2 @@
data/config.toml
data/announcements.json
+18 -1
View File
@@ -7,9 +7,12 @@ pipeline:
- go build -o segfautils - go build -o segfautils
dockerize_n_publish: dockerize_n_publish:
when: when:
branch : [master]
event: [push] event: [push]
name: dockerize and publish name: dockerize and publish
image: plugins/docker image: plugins/docker
registry: git.projectsegfau.lt
repo: git.projectsegfau.lt/projectsegfault/segfautils
settings: settings:
username: username:
from_secret: username from_secret: username
@@ -17,6 +20,20 @@ pipeline:
from_secret: password from_secret: password
repo: projectsegfault/segfautils repo: projectsegfault/segfautils
dockerfile: Dockerfile dockerfile: Dockerfile
dockerize_dev:
when:
event: [push]
image: plugins/docker
name: dockerize and publish dev
registry: git.projectsegfau.lt
repo: git.projectsegfau.lt/projectsegfault/segfautils
settings:
username:
from_secret: username
password:
from_secret: password
repo: projectsegfau.lt/segfautils
tags: dev
dockerfile: Dockerfile
+27 -2
View File
@@ -15,8 +15,33 @@ import (
var ( var (
authToken = config.AuthToken() authToken = config.AuthToken()
resAnn = config.OptAnn()
) )
func AnnCheck() {
if resAnn == "false" {
log.Println("[Segfautils] Announcements are disabled")
http.HandleFunc("/announcements", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Announcements are disabled.", http.StatusServiceUnavailable)
})
http.HandleFunc("/api/set/announcements", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "{\"enabled\": \"false\"}", http.StatusOK)
})
} else {
AnnPage()
http.HandleFunc("/api/set/announcements", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "{\"enabled\": \"true\"}", http.StatusOK)
})
Announcements()
}
}
func AnnPage() {
http.HandleFunc("/announcements", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "static/announcements.html")
})
}
func Announcements() { func Announcements() {
http.HandleFunc("/api/announcements", getAnnouncements) http.HandleFunc("/api/announcements", getAnnouncements)
http.HandleFunc("/api/announcements/post", handleAnnouncements) http.HandleFunc("/api/announcements/post", handleAnnouncements)
@@ -32,8 +57,8 @@ func handleAnnouncements(w http.ResponseWriter, r *http.Request) {
http.Error(w, "You need to provide the authorization token given to you by your system administrator in order to post an announcement.", http.StatusUnauthorized) http.Error(w, "You need to provide the authorization token given to you by your system administrator in order to post an announcement.", http.StatusUnauthorized)
return return
} else { } else {
if r.FormValue("title") == "" || r.FormValue("link") == "" || r.FormValue("severity") == "" { if r.FormValue("title") == "" || r.FormValue("severity") == "" {
http.Error(w, "Your request is not proper. Please add a title, link, and severity.", http.StatusBadRequest) http.Error(w, "Your request is not proper. Please add a title and severity.", http.StatusBadRequest)
return return
} else { } else {
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
+40 -6
View File
@@ -1,18 +1,16 @@
package api package api
import ( import (
"fmt"
"io"
"log" "log"
"net/http" "net/http"
"github.com/kataras/hcaptcha"
"fmt"
"io"
"net/url" "net/url"
"text/template"
"github.com/ProjectSegfault/segfautils/config" "github.com/ProjectSegfault/segfautils/config"
"github.com/ProjectSegfault/segfautils/utils" "github.com/ProjectSegfault/segfautils/utils"
"github.com/kataras/hcaptcha"
) )
var ( var (
@@ -20,8 +18,44 @@ var (
secretKey = config.HCaptchaSecretKey() secretKey = config.HCaptchaSecretKey()
webhookURL = config.WebhookURL() webhookURL = config.WebhookURL()
client = hcaptcha.New(secretKey) /* See `Client.FailureHandler` too. */ client = hcaptcha.New(secretKey) /* See `Client.FailureHandler` too. */
resForm = config.OptForm()
) )
func FormCheck() {
if resForm == "false" {
log.Println("[Segfautils] Contact form is disabled")
http.HandleFunc("/form", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Form is disabled.", http.StatusServiceUnavailable)
})
http.HandleFunc("/api/set/form", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "{\"enabled\": \"false\"}", http.StatusOK)
})
} else {
FormPage()
http.HandleFunc("/api/set/form", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "{\"enabled\": \"true\"}", http.StatusOK)
})
Form()
}
}
func FormPage() {
type StaticThing struct {
HCaptchaSiteKey string
}
tmpl_form := template.Must(template.ParseFiles("static/form.html"))
http.HandleFunc("/form/", func(w http.ResponseWriter, r *http.Request) {
hcaptcha_site_key := config.HCaptchaSiteKey()
data := StaticThing{
HCaptchaSiteKey: hcaptcha_site_key,
}
tmpl_form.Execute(w, data)
})
}
func Form() { func Form() {
http.HandleFunc("/api/form", client.HandlerFunc(theActualFormCode)) http.HandleFunc("/api/form", client.HandlerFunc(theActualFormCode))
} }
+1 -1
View File
@@ -15,7 +15,7 @@ func AuthToken() string {
viper.AddConfigPath("./data") viper.AddConfigPath("./data")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
log.Println("Error reading config for getting segfautils.auth_token", err.Error()) log.Println("Error reading config. Error getting: segfautils.auth_token", err.Error())
} }
result := viper.GetString("segfautils.auth_token") result := viper.GetString("segfautils.auth_token")
return result return result
+1 -1
View File
@@ -11,7 +11,7 @@ func HCaptchaSecretKey() string {
viper.AddConfigPath("./data") viper.AddConfigPath("./data")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
log.Println("Error reading config for getting hcaptcha.secret_key", err.Error()) log.Println("Error reading config. Error getting: hcaptcha.secret_key", err.Error())
} }
result := viper.GetString("hcaptcha.secret_key") result := viper.GetString("hcaptcha.secret_key")
return result return result
+1 -1
View File
@@ -11,7 +11,7 @@ func HCaptchaSiteKey() string {
viper.AddConfigPath("./data") viper.AddConfigPath("./data")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
log.Println("Error reading config for getting hcaptcha.site_key", err.Error()) log.Println("Error reading config. Error getting: hcaptcha.site_key", err.Error())
} }
result := viper.GetString("hcaptcha.site_key") result := viper.GetString("hcaptcha.site_key")
return result return result
+18
View File
@@ -0,0 +1,18 @@
package config
import (
"log"
"github.com/spf13/viper"
)
func OptAnn() string {
viper.SetConfigName("config")
viper.AddConfigPath("./data")
err := viper.ReadInConfig()
if err != nil {
log.Println("Error reading config. Error getting: options.announce", err.Error())
}
result := viper.GetString("options.announce")
return result
}
+18
View File
@@ -0,0 +1,18 @@
package config
import (
"log"
"github.com/spf13/viper"
)
func OptForm() string {
viper.SetConfigName("config")
viper.AddConfigPath("./data")
err := viper.ReadInConfig()
if err != nil {
log.Println("Error reading config. Error getting: options.form", err.Error())
}
result := viper.GetString("options.form")
return result
}
+1 -1
View File
@@ -12,7 +12,7 @@ func Port() string {
viper.AddConfigPath("./data") viper.AddConfigPath("./data")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
log.Println("Error reading config for getting segfautils.port", err.Error()) log.Println("Error reading config. Error getting: segfautils.port", err.Error())
} }
result := strconv.Itoa(viper.GetInt("segfautils.port")) result := strconv.Itoa(viper.GetInt("segfautils.port"))
return result return result
+1 -1
View File
@@ -11,7 +11,7 @@ func WebhookURL() string {
viper.AddConfigPath("./data") viper.AddConfigPath("./data")
err := viper.ReadInConfig() err := viper.ReadInConfig()
if err != nil { if err != nil {
log.Println("Error reading config for getting segfautils.webhook_url", err.Error()) log.Println("Error reading config. Error getting: segfautils.webhook_url", err.Error())
} }
result := viper.GetString("segfautils.webhook_url") result := viper.GetString("segfautils.webhook_url")
return result return result
+4
View File
@@ -6,3 +6,7 @@ auth_token = "YOURAUTHTOKEN"
[hcaptcha] [hcaptcha]
site_key = "YOURSITEKEY" site_key = "YOURSITEKEY"
secret_key = "YOURSECRETKEY" secret_key = "YOURSECRETKEY"
[options]
announce = true
form = false
+6 -19
View File
@@ -12,18 +12,13 @@ import (
) )
type StaticThingy struct { type StaticThingy struct {
Port string Port string
HCaptchaSiteKey string
} }
var port string
var shit bool
func main() { func main() {
log.Println("[Segfautils] Starting") log.Println("[Segfautils] Starting")
utils.CheckConfig() utils.CheckConfig()
log.Println("[HTTP] Starting server")
hcaptcha_site_key := config.HCaptchaSiteKey()
tmpl := template.Must(template.ParseFiles("static/index.html")) tmpl := template.Must(template.ParseFiles("static/index.html"))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := StaticThingy{ data := StaticThingy{
@@ -32,22 +27,14 @@ func main() {
tmpl.Execute(w, data) tmpl.Execute(w, data)
}) })
tmpl_form := template.Must(template.ParseFiles("static/form.html")) log.Println("[HTTP] Starting server")
http.HandleFunc("/form/", func(w http.ResponseWriter, r *http.Request) { api.AnnCheck()
data := StaticThingy{ api.FormCheck()
HCaptchaSiteKey: hcaptcha_site_key,
}
tmpl_form.Execute(w, data)
})
http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "welcome to hell") io.WriteString(w, "welcome to hell")
}) })
http.HandleFunc("/announcements", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "static/announcements.html")
})
api.Form()
api.Announcements()
log.Println("[HTTP] HTTP server is now running at " + config.Port() + "!") log.Println("[HTTP] HTTP server is now running at " + config.Port() + "!")
log.Println(http.ListenAndServe(":"+config.Port(), nil)) log.Println(http.ListenAndServe(":"+config.Port(), nil))
} }
+108 -4
View File
@@ -11,6 +11,107 @@
color: #fff; color: #fff;
font-family: 'JetBrains Mono', 'JetBrainsMono Nerd Font', monospace font-family: 'JetBrains Mono', 'JetBrainsMono Nerd Font', monospace
} }
.container {
width: 100%;
max-width: 400px;
margin: 0 auto;
position: relative;
}
#contact input[type="token"],
#contact input[type="link"],
#contact textarea,
#contact select,
#contact button[type="submit"] {
font: 500 15px/16px "Roboto", sans-serif;
}
.container h1 {
text-align: center;
margin: 0;
padding: 0;
font-size: 2rem;
}
#contact textarea {
text-align: center;
border-radius: 5px;
margin-top: 10px;
width: 100%;
border: none;
color: #FFF;
background: #3b3b3b;
margin: 0 0 5px;
padding: 10px;
height: 100px;
max-width: 100%;
resize: none;
}
#contact input, select {
text-align: center;
border-radius: 5px;
color: #FFF;
width: 100%;
border: none;
background: #3b3b3b;
margin: 0 0 5px;
padding: 10px;
max-width: 100%;
}
#contact select {
width: 105%;
max-width: 105%;
}
#contact button[type="submit"] {
cursor: pointer;
width: 105%;
border: none;
background: #00d4aa;
color: #252525;
margin: 0 0 5px;
padding: 10px;
font-size: 15px;
border-radius: 5px;
}
#contact button[type="submit"]:hover {
background: #00a484;
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background-color 0.3s ease-in-out;
}
#contact button[type="submit"]:active {
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}
#contact button[type="delete"] {
cursor: pointer;
width: 105%;
border: none;
background: #d10006;
color: #FFF;
margin: 0 0 5px;
padding: 10px;
font-size: 15px;
border-radius: 5px;
}
#contact button[type="delete"]:hover {
background: #990005;
-webkit-transition: background 0.3s ease-in-out;
-moz-transition: background 0.3s ease-in-out;
transition: background-color 0.3s ease-in-out;
}
#contact button[type="delete"]:active {
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}
a { a {
color: #00d4aa; color: #00d4aa;
@@ -22,8 +123,10 @@
</style> </style>
</head> </head>
<body> <body>
<div class="container">
<h1>Post Announcement</h1> <h1>Post Announcement</h1>
<form <form
id="contact"
action="/api/announcements/post" action="/api/announcements/post"
method="POST" method="POST"
target="_blank" target="_blank"
@@ -45,7 +148,6 @@
</select> </select>
</div> </div>
<textarea <textarea
id="title"
name="title" name="title"
rows="4" rows="4"
cols="25" cols="25"
@@ -58,10 +160,11 @@
placeholder="Your link for more details" placeholder="Your link for more details"
/> />
<br /> <br />
<input type="submit" value="Submit" /> <button type="submit" />Submit</button>
</form> </form>
<h1>Delete Announcement</h1> <h1 style="margin-top: 20px;">Delete Announcement</h1>
<form <form
id="contact"
action="/api/announcements/delete" action="/api/announcements/delete"
method="POST" method="POST"
target="_blank" target="_blank"
@@ -75,7 +178,8 @@
/> />
<br /> <br />
</div> </div>
<input type="submit" value="Submit" /> <button type="delete"/>Delete</button>
</form> </form>
</div>
</body> </body>
</html> </html>