Copied over SWAssistant and CDR backend
Started converting them to new backend
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Caleb Gardner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,44 @@
|
||||
# cdr-backend
|
||||
|
||||
Stupid backend for [CDR]("https://github.com/CalebQ42/CustomDiceRoller").
|
||||
|
||||
## APIs
|
||||
|
||||
### Dice
|
||||
|
||||
Dice sharing
|
||||
|
||||
> POST: /upload?key={api_key}
|
||||
|
||||
Upload a die.
|
||||
|
||||
Request Body:
|
||||
|
||||
```json
|
||||
{
|
||||
// Die data
|
||||
}
|
||||
```
|
||||
|
||||
Note: Only allows up to 1MB of data. If over 1MB returns 413. Further limits might be imposed in the future.
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "die ID",
|
||||
"expiration": 0 // Unix time (Seconds) of expiration
|
||||
}
|
||||
```
|
||||
|
||||
> GET: /die/{die id}?key={api_key}
|
||||
|
||||
Get an uploaded die.
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
// die data minus uid
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,61 @@
|
||||
package cdr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend/db"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type CDRBackend struct {
|
||||
back *backend.Backend
|
||||
db *mongo.Database
|
||||
}
|
||||
|
||||
func NewBackend(back *backend.Backend, db *mongo.Database) *CDRBackend {
|
||||
go func() {
|
||||
for range time.Tick(time.Hour) {
|
||||
log.Println("CDR: Deleting expired dice")
|
||||
res, err := db.Collection("profiles").DeleteMany(context.TODO(), bson.M{"expiration": bson.M{"$lt": time.Now().Unix()}})
|
||||
if err == mongo.ErrNoDocuments {
|
||||
continue
|
||||
}
|
||||
log.Println("CDR: Deleted", res.DeletedCount, "dice")
|
||||
}
|
||||
}()
|
||||
return &CDRBackend{
|
||||
back: back,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (b CDRBackend) AppID() string {
|
||||
return "cdr"
|
||||
}
|
||||
|
||||
func (b CDRBackend) CountTable() backend.CountTable {
|
||||
return db.NewMongoTable[backend.CountLog](b.db.Collection("logs"))
|
||||
}
|
||||
|
||||
func (b CDRBackend) CrashTable() backend.CrashTable {
|
||||
return db.NewMongoCrashTable(b.db.Collection("crashes"), b.db.Collection("crashArchive"))
|
||||
}
|
||||
|
||||
func (s CDRBackend) AddCrash(cr backend.IndividualCrash) bool {
|
||||
res := s.db.Collection("versions").FindOne(context.TODO(), bson.M{"version": cr.Version})
|
||||
return res.Err() != mongo.ErrNoDocuments
|
||||
}
|
||||
|
||||
func (b CDRBackend) Extension(mux *http.ServeMux) {
|
||||
mux.HandleFunc("POST /cdr/die", b.UploadDie)
|
||||
mux.HandleFunc("GET /cdr/die/{dieID}", b.GetDie)
|
||||
|
||||
//Legacy (TODO: remove this after a month or two after the applciation gets updated)
|
||||
mux.HandleFunc("POST /upload", b.UploadDie)
|
||||
mux.HandleFunc("GET /die/{dieID}", b.GetDie)
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package cdr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||
"github.com/google/uuid"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type UploadedDie struct {
|
||||
Die map[string]any `json:"die" bson:"die"`
|
||||
ID string `json:"id" bson:"_id"`
|
||||
Expiration int64 `json:"expiration" bson:"expiration"`
|
||||
}
|
||||
|
||||
func (b CDRBackend) UploadDie(w http.ResponseWriter, r *http.Request) {
|
||||
hdr, err := b.back.VerifyHeader(w, r, "rooms", false)
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
if r.Body == nil {
|
||||
backend.ReturnError(w, http.StatusBadRequest, "bad request", "Application sent a bad request")
|
||||
return
|
||||
}
|
||||
bod, err := io.ReadAll(r.Body)
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
backend.ReturnError(w, http.StatusBadRequest, "bad request", "Application sent a bad request")
|
||||
return
|
||||
}
|
||||
if len(bod) > 1048576 { //1MB
|
||||
backend.ReturnError(w, http.StatusRequestEntityTooLarge, "too large", "Die is too large to upload")
|
||||
return
|
||||
}
|
||||
var toUpload = UploadedDie{
|
||||
Die: make(map[string]any),
|
||||
ID: uuid.New().String(),
|
||||
Expiration: time.Now().Add(12 * time.Hour).Round(time.Hour).Unix(),
|
||||
}
|
||||
err = json.Unmarshal(bod, &toUpload.Die)
|
||||
if err != nil {
|
||||
backend.ReturnError(w, http.StatusBadRequest, "bad request", "Application sent a bad request")
|
||||
return
|
||||
}
|
||||
if toUpload.Die["uuid"] != nil {
|
||||
delete(toUpload.Die, "uuid")
|
||||
}
|
||||
_, err = b.db.Collection("dice").InsertOne(context.TODO(), toUpload)
|
||||
if err != nil {
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
log.Println("error inserting die:", err)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(map[string]any{"id": toUpload.ID, "expiration": toUpload.Expiration})
|
||||
}
|
||||
|
||||
func (b CDRBackend) GetDie(w http.ResponseWriter, r *http.Request) {
|
||||
res := b.db.Collection("dice").FindOne(context.TODO(), bson.M{"_id": r.PathValue("dieID")})
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
backend.ReturnError(w, 404, "not found", "Die with the given id is not found")
|
||||
return
|
||||
} else if res.Err() != nil {
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
log.Println("error getting CDR die:", res.Err())
|
||||
return
|
||||
}
|
||||
var dieGet UploadedDie
|
||||
err := res.Decode(&dieGet)
|
||||
if err != nil {
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
log.Println("error decoding die:", err)
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(dieGet.Die)
|
||||
}
|
||||
Reference in New Issue
Block a user