Compare commits
30 Commits
optional
...
options-pu
Author | SHA1 | Date | |
---|---|---|---|
79f5117e63
|
|||
0cdcadb27b
|
|||
fcf66afb14
|
|||
6bdbf3b83d
|
|||
1c2e6e3da9
|
|||
65d35747fc
|
|||
af39a52971
|
|||
16ea5c3138
|
|||
0beb8a33de
|
|||
3abdbde812
|
|||
bfdc165346
|
|||
64a39ac5e5
|
|||
950d65ca59
|
|||
65634751b6
|
|||
7542cfba4a
|
|||
9a504d1638
|
|||
e614ab79fa
|
|||
41209f3ee3
|
|||
977136d9c2 | |||
b05c48cfbb | |||
11a792d96c | |||
427bec5081
|
|||
dc69cc447d
|
|||
c5b3c2bd98
|
|||
e8d8b9b096 | |||
a18f76d206 | |||
50b058c1d2
|
|||
fc5fc6a91d
|
|||
cbd31e8893
|
|||
f0ed8fbc39 |
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -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
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
data/config.toml
|
||||||
|
data/announcements.json
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
46
api/form.go
46
api/form.go
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
config/optionannounce.go
Normal file
18
config/optionannounce.go
Normal 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
config/optionform.go
Normal file
18
config/optionform.go
Normal 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
|
||||||
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
25
main.go
25
main.go
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user