mirror of
https://github.com/lus/pasty.git
synced 2023-08-10 21:13:09 +03:00
Switch from snowflake to random string ID system
This commit is contained in:
parent
a1cd915759
commit
5585a26ab0
@ -7,6 +7,7 @@ Pasty is a fast and lightweight code pasting server
|
|||||||
| `PASTY_WEB_ADDRESS` | `:8080` | `string` | Defines the address the web server listens to |
|
| `PASTY_WEB_ADDRESS` | `:8080` | `string` | Defines the address the web server listens to |
|
||||||
| `PASTY_STORAGE_TYPE` | `file` | `string` | Defines the storage type the pastes are saved to |
|
| `PASTY_STORAGE_TYPE` | `file` | `string` | Defines the storage type the pastes are saved to |
|
||||||
| `PASTY_HASTEBIN_SUPPORT` | `false` | `bool` | Defines whether or not the `POST /documents` endpoint should be enabled, as known from the hastebin servers |
|
| `PASTY_HASTEBIN_SUPPORT` | `false` | `bool` | Defines whether or not the `POST /documents` endpoint should be enabled, as known from the hastebin servers |
|
||||||
|
| `PASTY_ID_LENGTH` | `6` | `number` | Defines the length of the ID of a paste |
|
||||||
| `PASTY_DELETION_TOKEN_LENGTH` | `12` | `number` | Defines the length of the deletion token of a paste |
|
| `PASTY_DELETION_TOKEN_LENGTH` | `12` | `number` | Defines the length of the deletion token of a paste |
|
||||||
| `PASTY_RATE_LIMIT` | `30-M` | `string` | Defines the rate limit of the API (see https://github.com/ulule/limiter#usage) |
|
| `PASTY_RATE_LIMIT` | `30-M` | `string` | Defines the rate limit of the API (see https://github.com/ulule/limiter#usage) |
|
||||||
|
|
||||||
@ -19,6 +20,8 @@ Every single one of them has its own configuration variables:
|
|||||||
|---------------------------|---------------|----------|-----------------------------------------------------------|
|
|---------------------------|---------------|----------|-----------------------------------------------------------|
|
||||||
| `PASTY_STORAGE_FILE_PATH` | `./data` | `string` | Defines the file path the paste files are being saved to |
|
| `PASTY_STORAGE_FILE_PATH` | `./data` | `string` | Defines the file path the paste files are being saved to |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### S3 (`s3`)
|
### S3 (`s3`)
|
||||||
| Environment Variable | Default Value | Type | Description |
|
| Environment Variable | Default Value | Type | Description |
|
||||||
|--------------------------------|---------------|----------|-------------------------------------------------------------------------------------------|
|
|--------------------------------|---------------|----------|-------------------------------------------------------------------------------------------|
|
||||||
@ -30,6 +33,8 @@ Every single one of them has its own configuration variables:
|
|||||||
| `STORAGE_S3_REGION` | `<empty>` | `string` | Defines the region of the S3 storage |
|
| `STORAGE_S3_REGION` | `<empty>` | `string` | Defines the region of the S3 storage |
|
||||||
| `STORAGE_S3_BUCKET` | `pasty` | `string` | Defines the name of the S3 bucket (has to be created before setup) |
|
| `STORAGE_S3_BUCKET` | `pasty` | `string` | Defines the name of the S3 bucket (has to be created before setup) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### MongoDB (`mongodb`)
|
### MongoDB (`mongodb`)
|
||||||
| Environment Variable | Default Value | Type | Description |
|
| Environment Variable | Default Value | Type | Description |
|
||||||
|-------------------------------------|--------------------------------------------|----------|-----------------------------------------------------------------|
|
|-------------------------------------|--------------------------------------------|----------|-----------------------------------------------------------------|
|
||||||
|
1
go.mod
1
go.mod
@ -4,7 +4,6 @@ go 1.15
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b
|
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b
|
||||||
github.com/bwmarrin/snowflake v0.3.0
|
|
||||||
github.com/fasthttp/router v1.2.4
|
github.com/fasthttp/router v1.2.4
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/klauspost/compress v1.10.11 // indirect
|
github.com/klauspost/compress v1.10.11 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -5,8 +5,6 @@ github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDa
|
|||||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
github.com/aws/aws-sdk-go v1.29.15 h1:0ms/213murpsujhsnxnNKNeVouW60aJqSd992Ks3mxs=
|
github.com/aws/aws-sdk-go v1.29.15 h1:0ms/213murpsujhsnxnNKNeVouW60aJqSd992Ks3mxs=
|
||||||
github.com/aws/aws-sdk-go v1.29.15/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
|
github.com/aws/aws-sdk-go v1.29.15/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
|
||||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
|
||||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -2,13 +2,10 @@ package pastes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Lukaesebrot/pasty/internal/env"
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
"math/rand"
|
"github.com/Lukaesebrot/pasty/internal/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// deletionTokenContents represents the characters a deletion token may contain
|
|
||||||
const deletionTokenContents = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#+-.,"
|
|
||||||
|
|
||||||
// generateDeletionToken generates a new deletion token
|
// generateDeletionToken generates a new deletion token
|
||||||
func generateDeletionToken() (string, error) {
|
func generateDeletionToken() (string, error) {
|
||||||
// Read the deletion token length
|
// Read the deletion token length
|
||||||
@ -19,9 +16,5 @@ func generateDeletionToken() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the deletion token
|
// Generate the deletion token
|
||||||
bytes := make([]byte, length)
|
return utils.RandomString(length), nil
|
||||||
for i := range bytes {
|
|
||||||
bytes[i] = deletionTokenContents[rand.Int63()%int64(len(deletionTokenContents))]
|
|
||||||
}
|
|
||||||
return string(bytes), nil
|
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,18 @@ package pastes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/alexedwards/argon2id"
|
"github.com/alexedwards/argon2id"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
snowflakeNode, _ = snowflake.NewNode(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// snowflakeNode holds the current snowflake node
|
|
||||||
var snowflakeNode *snowflake.Node
|
|
||||||
|
|
||||||
// Paste represents a saved paste
|
// Paste represents a saved paste
|
||||||
type Paste struct {
|
type Paste struct {
|
||||||
ID snowflake.ID `json:"id" bson:"_id"`
|
ID string `json:"id" bson:"_id"`
|
||||||
Content string `json:"content" bson:"content"`
|
Content string `json:"content" bson:"content"`
|
||||||
SuggestedSyntaxType string `json:"suggestedSyntaxType" bson:"suggestedSyntaxType"`
|
SuggestedSyntaxType string `json:"suggestedSyntaxType" bson:"suggestedSyntaxType"`
|
||||||
DeletionToken string `json:"deletionToken" bson:"deletionToken"`
|
DeletionToken string `json:"deletionToken" bson:"deletionToken"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new paste object using the given content
|
// Create creates a new paste object using the given content
|
||||||
func Create(content string) (*Paste, error) {
|
func Create(id, content string) (*Paste, error) {
|
||||||
// TODO: Generate the suggested syntax type
|
// TODO: Generate the suggested syntax type
|
||||||
suggestedSyntaxType := ""
|
suggestedSyntaxType := ""
|
||||||
|
|
||||||
@ -33,7 +25,7 @@ func Create(content string) (*Paste, error) {
|
|||||||
|
|
||||||
// Return the paste object
|
// Return the paste object
|
||||||
return &Paste{
|
return &Paste{
|
||||||
ID: snowflakeNode.Generate(),
|
ID: id,
|
||||||
Content: content,
|
Content: content,
|
||||||
SuggestedSyntaxType: suggestedSyntaxType,
|
SuggestedSyntaxType: suggestedSyntaxType,
|
||||||
DeletionToken: deletionToken,
|
DeletionToken: deletionToken,
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Lukaesebrot/pasty/internal/env"
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,9 +14,9 @@ var Current Driver
|
|||||||
type Driver interface {
|
type Driver interface {
|
||||||
Initialize() error
|
Initialize() error
|
||||||
Terminate() error
|
Terminate() error
|
||||||
Get(id snowflake.ID) (*pastes.Paste, error)
|
Get(id string) (*pastes.Paste, error)
|
||||||
Save(paste *pastes.Paste) error
|
Save(paste *pastes.Paste) error
|
||||||
Delete(id snowflake.ID) error
|
Delete(id string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads the current storage driver
|
// Load loads the current storage driver
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/Lukaesebrot/pasty/internal/env"
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -27,9 +26,9 @@ func (driver *FileDriver) Terminate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get loads a paste
|
// Get loads a paste
|
||||||
func (driver *FileDriver) Get(id snowflake.ID) (*pastes.Paste, error) {
|
func (driver *FileDriver) Get(id string) (*pastes.Paste, error) {
|
||||||
// Read the file
|
// Read the file
|
||||||
data, err := ioutil.ReadFile(filepath.Join(driver.filePath, id.String()+".json"))
|
data, err := ioutil.ReadFile(filepath.Join(driver.filePath, id+".json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -55,7 +54,7 @@ func (driver *FileDriver) Save(paste *pastes.Paste) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the file to save the paste to
|
// Create the file to save the paste to
|
||||||
file, err := os.Create(filepath.Join(driver.filePath, paste.ID.String()+".json"))
|
file, err := os.Create(filepath.Join(driver.filePath, paste.ID+".json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -67,6 +66,6 @@ func (driver *FileDriver) Save(paste *pastes.Paste) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a paste
|
// Delete deletes a paste
|
||||||
func (driver *FileDriver) Delete(id snowflake.ID) error {
|
func (driver *FileDriver) Delete(id string) error {
|
||||||
return os.Remove(filepath.Join(driver.filePath, id.String()+".json"))
|
return os.Remove(filepath.Join(driver.filePath, id+".json"))
|
||||||
}
|
}
|
||||||
|
29
internal/storage/id_generation.go
Normal file
29
internal/storage/id_generation.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
|
"github.com/Lukaesebrot/pasty/internal/utils"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AcquireID generates a new unique ID
|
||||||
|
func AcquireID() (string, error) {
|
||||||
|
// Read the ID length
|
||||||
|
rawLength := env.Get("ID_LENGTH", "6")
|
||||||
|
length, err := strconv.Atoi(rawLength)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the unique ID
|
||||||
|
for {
|
||||||
|
id := utils.RandomString(length)
|
||||||
|
paste, err := Current.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if paste == nil {
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"github.com/Lukaesebrot/pasty/internal/env"
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
@ -50,7 +49,7 @@ func (driver *MongoDBDriver) Terminate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get loads a paste
|
// Get loads a paste
|
||||||
func (driver *MongoDBDriver) Get(id snowflake.ID) (*pastes.Paste, error) {
|
func (driver *MongoDBDriver) Get(id string) (*pastes.Paste, error) {
|
||||||
// Define the collection to use for this database operation
|
// Define the collection to use for this database operation
|
||||||
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ func (driver *MongoDBDriver) Get(id snowflake.ID) (*pastes.Paste, error) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Try to retrieve the corresponding paste document
|
// Try to retrieve the corresponding paste document
|
||||||
filter := bson.M{"_id": id.String()}
|
filter := bson.M{"_id": id}
|
||||||
result := collection.FindOne(ctx, filter)
|
result := collection.FindOne(ctx, filter)
|
||||||
err := result.Err()
|
err := result.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -90,7 +89,7 @@ func (driver *MongoDBDriver) Save(paste *pastes.Paste) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a paste
|
// Delete deletes a paste
|
||||||
func (driver *MongoDBDriver) Delete(id snowflake.ID) error {
|
func (driver *MongoDBDriver) Delete(id string) error {
|
||||||
// Define the collection to use for this database operation
|
// Define the collection to use for this database operation
|
||||||
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
collection := driver.client.Database(driver.database).Collection(driver.collection)
|
||||||
|
|
||||||
@ -99,7 +98,7 @@ func (driver *MongoDBDriver) Delete(id snowflake.ID) error {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Delete the document
|
// Delete the document
|
||||||
filter := bson.M{"_id": id.String()}
|
filter := bson.M{"_id": id}
|
||||||
_, err := collection.DeleteOne(ctx, filter)
|
_, err := collection.DeleteOne(ctx, filter)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/Lukaesebrot/pasty/internal/env"
|
"github.com/Lukaesebrot/pasty/internal/env"
|
||||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -39,9 +38,9 @@ func (driver *S3Driver) Terminate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get loads a paste
|
// Get loads a paste
|
||||||
func (driver *S3Driver) Get(id snowflake.ID) (*pastes.Paste, error) {
|
func (driver *S3Driver) Get(id string) (*pastes.Paste, error) {
|
||||||
// Read the object
|
// Read the object
|
||||||
object, err := driver.client.GetObject(context.Background(), driver.bucket, id.String()+".json", minio.GetObjectOptions{})
|
object, err := driver.client.GetObject(context.Background(), driver.bucket, id+".json", minio.GetObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -69,13 +68,13 @@ func (driver *S3Driver) Save(paste *pastes.Paste) error {
|
|||||||
|
|
||||||
// Put the object
|
// Put the object
|
||||||
reader := bytes.NewReader(jsonBytes)
|
reader := bytes.NewReader(jsonBytes)
|
||||||
_, err = driver.client.PutObject(context.Background(), driver.bucket, paste.ID.String()+".json", reader, reader.Size(), minio.PutObjectOptions{
|
_, err = driver.client.PutObject(context.Background(), driver.bucket, paste.ID+".json", reader, reader.Size(), minio.PutObjectOptions{
|
||||||
ContentType: "application/json",
|
ContentType: "application/json",
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes a paste
|
// Delete deletes a paste
|
||||||
func (driver *S3Driver) Delete(id snowflake.ID) error {
|
func (driver *S3Driver) Delete(id string) error {
|
||||||
return driver.client.RemoveObject(context.Background(), driver.bucket, id.String()+".json", minio.RemoveObjectOptions{})
|
return driver.client.RemoveObject(context.Background(), driver.bucket, id+".json", minio.RemoveObjectOptions{})
|
||||||
}
|
}
|
||||||
|
15
internal/utils/randomString.go
Normal file
15
internal/utils/randomString.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
// stringContents holds the chars a random string can contain
|
||||||
|
const stringContents = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
|
||||||
|
// RandomString returns a random string with the given length
|
||||||
|
func RandomString(length int) string {
|
||||||
|
bytes := make([]byte, length)
|
||||||
|
for i := range bytes {
|
||||||
|
bytes[i] = stringContents[rand.Int63()%int64(len(stringContents))]
|
||||||
|
}
|
||||||
|
return string(bytes)
|
||||||
|
}
|
@ -24,8 +24,16 @@ func HastebinSupportHandler(ctx *fasthttp.RequestCtx) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Acquire the paste ID
|
||||||
|
id, err := storage.AcquireID()
|
||||||
|
if err != nil {
|
||||||
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
|
ctx.SetBodyString(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Create the paste object
|
// Create the paste object
|
||||||
paste, err := pastes.Create(content)
|
paste, err := pastes.Create(id, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
ctx.SetBodyString(err.Error())
|
ctx.SetBodyString(err.Error())
|
||||||
@ -50,7 +58,7 @@ func HastebinSupportHandler(ctx *fasthttp.RequestCtx) {
|
|||||||
|
|
||||||
// Respond with the paste key
|
// Respond with the paste key
|
||||||
jsonData, _ := json.Marshal(map[string]string{
|
jsonData, _ := json.Marshal(map[string]string{
|
||||||
"key": paste.ID.String(),
|
"key": paste.ID,
|
||||||
})
|
})
|
||||||
ctx.SetBody(jsonData)
|
ctx.SetBody(jsonData)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||||
"github.com/Lukaesebrot/pasty/internal/storage"
|
"github.com/Lukaesebrot/pasty/internal/storage"
|
||||||
"github.com/bwmarrin/snowflake"
|
|
||||||
"github.com/fasthttp/router"
|
"github.com/fasthttp/router"
|
||||||
limitFasthttp "github.com/ulule/limiter/v3/drivers/middleware/fasthttp"
|
limitFasthttp "github.com/ulule/limiter/v3/drivers/middleware/fasthttp"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
@ -19,13 +18,8 @@ func InitializePastesController(group *router.Group, rateLimiterMiddleware *limi
|
|||||||
|
|
||||||
// v1GetPaste handles the 'GET /v1/pastes/{id}' endpoint
|
// v1GetPaste handles the 'GET /v1/pastes/{id}' endpoint
|
||||||
func v1GetPaste(ctx *fasthttp.RequestCtx) {
|
func v1GetPaste(ctx *fasthttp.RequestCtx) {
|
||||||
// Parse the ID
|
// Read the ID
|
||||||
id, err := snowflake.ParseString(ctx.UserValue("id").(string))
|
id := ctx.UserValue("id").(string)
|
||||||
if err != nil {
|
|
||||||
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
|
||||||
ctx.SetBodyString("invalid ID format")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the paste
|
// Retrieve the paste
|
||||||
paste, err := storage.Current.Get(id)
|
paste, err := storage.Current.Get(id)
|
||||||
@ -68,8 +62,16 @@ func v1PostPaste(ctx *fasthttp.RequestCtx) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Acquire the paste ID
|
||||||
|
id, err := storage.AcquireID()
|
||||||
|
if err != nil {
|
||||||
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
|
ctx.SetBodyString(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Create the paste object
|
// Create the paste object
|
||||||
paste, err := pastes.Create(values["content"])
|
paste, err := pastes.Create(id, values["content"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
ctx.SetBodyString(err.Error())
|
ctx.SetBodyString(err.Error())
|
||||||
@ -105,17 +107,12 @@ func v1PostPaste(ctx *fasthttp.RequestCtx) {
|
|||||||
|
|
||||||
// v1DeletePaste handles the 'DELETE /v1/pastes/{id}'
|
// v1DeletePaste handles the 'DELETE /v1/pastes/{id}'
|
||||||
func v1DeletePaste(ctx *fasthttp.RequestCtx) {
|
func v1DeletePaste(ctx *fasthttp.RequestCtx) {
|
||||||
// Parse the ID
|
// Read the ID
|
||||||
id, err := snowflake.ParseString(ctx.UserValue("id").(string))
|
id := ctx.UserValue("id").(string)
|
||||||
if err != nil {
|
|
||||||
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
|
||||||
ctx.SetBodyString("invalid ID format")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal the body
|
// Unmarshal the body
|
||||||
values := make(map[string]string)
|
values := make(map[string]string)
|
||||||
err = json.Unmarshal(ctx.PostBody(), &values)
|
err := json.Unmarshal(ctx.PostBody(), &values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
ctx.SetStatusCode(fasthttp.StatusBadRequest)
|
||||||
ctx.SetBodyString("invalid request body")
|
ctx.SetBodyString("invalid request body")
|
||||||
|
Loading…
Reference in New Issue
Block a user