Add option to define ID and modification token generation characters (#17)

This commit is contained in:
Lukas Schulte Pelkum 2021-07-24 17:00:29 +02:00
parent 7af1f9431b
commit e8f7fa239e
No known key found for this signature in database
GPG Key ID: 408DA7CA81DB885C
7 changed files with 47 additions and 44 deletions

View File

@ -72,17 +72,19 @@ Pasty will be available at http://localhost:8080.
--- ---
## General environment variables ## General environment variables
| Environment Variable | Default Value | Type | Description | | Environment Variable | Default Value | Type | Description |
|-----------------------------------|---------------|----------|----------------------------------------------------------------------------------------------------------------------------| |---------------------------------------|------------------------------------------------------------------|----------|----------------------------------------------------------------------------------------------------------------------------|
| `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_ID_LENGTH` | `6` | `number` | Defines the length of the ID of a paste |
| `PASTY_MODIFICATION_TOKENS` | `true` | `bool` | Defines whether or not modification tokens should be generated | | `PASTY_ID_CHARACTERS` | `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789` | `string` | Defines the characters to use when generating paste IDs |
| `PASTY_MODIFICATION_TOKEN_MASTER` | `<empty>` | `string` | Defines the master modification token which is authorized to modify every paste (even if modification tokens are disabled) | | `PASTY_MODIFICATION_TOKENS` | `true` | `bool` | Defines whether or not modification tokens should be generated |
| `PASTY_MODIFICATION_TOKEN_LENGTH` | `12` | `number` | Defines the length of the modification token of a paste | | `PASTY_MODIFICATION_TOKEN_MASTER` | `<empty>` | `string` | Defines the master modification token which is authorized to modify every paste (even if modification tokens are disabled) |
| `PASTY_RATE_LIMIT` | `30-M` | `string` | Defines the rate limit of the API (see https://github.com/ulule/limiter#usage) | | `PASTY_MODIFICATION_TOKEN_LENGTH` | `12` | `number` | Defines the length of the modification token of a paste |
| `PASTY_LENGTH_CAP` | `50000` | `number` | Defines the maximum amount of characters a paste is allowed to contain (a value `<= 0` means no limit) | | `PASTY_MODIFICATION_TOKEN_CHARACTERS` | `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789` | `string` | Defines the characters to use when generating modification tokens |
| `PASTY_RATE_LIMIT` | `30-M` | `string` | Defines the rate limit of the API (see https://github.com/ulule/limiter#usage) |
| `PASTY_LENGTH_CAP` | `50000` | `number` | Defines the maximum amount of characters a paste is allowed to contain (a value `<= 0` means no limit) |
## AutoDelete ## AutoDelete
Pasty provides an intuitive system to automatically delete pastes after a specific amount of time. You can configure it with the following variables: Pasty provides an intuitive system to automatically delete pastes after a specific amount of time. You can configure it with the following variables:

View File

@ -10,21 +10,23 @@ import (
// Config represents the general application configuration structure // Config represents the general application configuration structure
type Config struct { type Config struct {
WebAddress string WebAddress string
StorageType shared.StorageType StorageType shared.StorageType
HastebinSupport bool HastebinSupport bool
IDLength int IDLength int
ModificationTokens bool IDCharacters string
ModificationTokenMaster string ModificationTokens bool
ModificationTokenLength int ModificationTokenMaster string
RateLimit string ModificationTokenLength int
LengthCap int ModificationTokenCharacters string
AutoDelete *AutoDeleteConfig RateLimit string
Reports *ReportConfig LengthCap int
File *FileConfig AutoDelete *AutoDeleteConfig
Postgres *PostgresConfig Reports *ReportConfig
MongoDB *MongoDBConfig File *FileConfig
S3 *S3Config Postgres *PostgresConfig
MongoDB *MongoDBConfig
S3 *S3Config
} }
// AutoDeleteConfig represents the configuration specific for the AutoDelete behaviour // AutoDeleteConfig represents the configuration specific for the AutoDelete behaviour
@ -77,15 +79,17 @@ func Load() {
env.Load() env.Load()
Current = &Config{ Current = &Config{
WebAddress: env.MustString("WEB_ADDRESS", ":8080"), WebAddress: env.MustString("WEB_ADDRESS", ":8080"),
StorageType: shared.StorageType(strings.ToLower(env.MustString("STORAGE_TYPE", "file"))), StorageType: shared.StorageType(strings.ToLower(env.MustString("STORAGE_TYPE", "file"))),
HastebinSupport: env.MustBool("HASTEBIN_SUPPORT", false), HastebinSupport: env.MustBool("HASTEBIN_SUPPORT", false),
IDLength: env.MustInt("ID_LENGTH", 6), IDLength: env.MustInt("ID_LENGTH", 6),
ModificationTokens: env.MustBool("MODIFICATION_TOKENS", env.MustBool("DELETION_TOKENS", true)), // --- IDCharacters: env.MustString("ID_CHARACTERS", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
ModificationTokenMaster: env.MustString("MODIFICATION_TOKEN_MASTER", env.MustString("DELETION_TOKEN_MASTER", "")), // - We don't want to destroy peoples old configuration ModificationTokens: env.MustBool("MODIFICATION_TOKENS", env.MustBool("DELETION_TOKENS", true)), // ---
ModificationTokenLength: env.MustInt("MODIFICATION_TOKEN_LENGTH", env.MustInt("DELETION_TOKEN_LENGTH", 12)), // --- ModificationTokenMaster: env.MustString("MODIFICATION_TOKEN_MASTER", env.MustString("DELETION_TOKEN_MASTER", "")), // - We don't want to destroy peoples old configuration
RateLimit: env.MustString("RATE_LIMIT", "30-M"), ModificationTokenLength: env.MustInt("MODIFICATION_TOKEN_LENGTH", env.MustInt("DELETION_TOKEN_LENGTH", 12)), // ---
LengthCap: env.MustInt("LENGTH_CAP", 50_000), ModificationTokenCharacters: env.MustString("MODIFICATION_TOKEN_CHARACTERS", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
RateLimit: env.MustString("RATE_LIMIT", "30-M"),
LengthCap: env.MustInt("LENGTH_CAP", 50_000),
AutoDelete: &AutoDeleteConfig{ AutoDelete: &AutoDeleteConfig{
Enabled: env.MustBool("AUTODELETE", false), Enabled: env.MustBool("AUTODELETE", false),
Lifetime: env.MustDuration("AUTODELETE_LIFETIME", 720*time.Hour), Lifetime: env.MustDuration("AUTODELETE_LIFETIME", 720*time.Hour),

View File

@ -8,7 +8,7 @@ import (
// AcquireID generates a new unique ID // AcquireID generates a new unique ID
func AcquireID() (string, error) { func AcquireID() (string, error) {
for { for {
id := utils.RandomString(config.Current.IDLength) id := utils.RandomString(config.Current.IDCharacters, config.Current.IDLength)
paste, err := Current.Get(id) paste, err := Current.Get(id)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -5,15 +5,12 @@ import (
"time" "time"
) )
// stringContents holds the chars a random string can contain
const stringContents = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// RandomString returns a random string with the given length // RandomString returns a random string with the given length
func RandomString(length int) string { func RandomString(characters string, length int) string {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
bytes := make([]byte, length) bytes := make([]byte, length)
for i := range bytes { for i := range bytes {
bytes[i] = stringContents[rand.Int63()%int64(len(stringContents))] bytes[i] = characters[rand.Int63()%int64(len(characters))]
} }
return string(bytes) return string(bytes)
} }

View File

@ -52,7 +52,7 @@ func HastebinSupportHandler(ctx *fasthttp.RequestCtx) {
// Set a modification token // Set a modification token
if config.Current.ModificationTokens { if config.Current.ModificationTokens {
paste.ModificationToken = utils.RandomString(config.Current.ModificationTokenLength) paste.ModificationToken = utils.RandomString(config.Current.ModificationTokenCharacters, config.Current.ModificationTokenLength)
err = paste.HashModificationToken() err = paste.HashModificationToken()
if err != nil { if err != nil {

View File

@ -95,7 +95,7 @@ func v1PostPaste(ctx *fasthttp.RequestCtx) {
// Set a modification token // Set a modification token
modificationToken := "" modificationToken := ""
if config.Current.ModificationTokens { if config.Current.ModificationTokens {
modificationToken = utils.RandomString(config.Current.ModificationTokenLength) modificationToken = utils.RandomString(config.Current.ModificationTokenCharacters, config.Current.ModificationTokenLength)
paste.ModificationToken = modificationToken paste.ModificationToken = modificationToken
err = paste.HashModificationToken() err = paste.HashModificationToken()

View File

@ -146,7 +146,7 @@ func endpointCreatePaste(ctx *fasthttp.RequestCtx) {
// Create a new modification token if enabled // Create a new modification token if enabled
modificationToken := "" modificationToken := ""
if config.Current.ModificationTokens { if config.Current.ModificationTokens {
modificationToken = utils.RandomString(config.Current.ModificationTokenLength) modificationToken = utils.RandomString(config.Current.ModificationTokenCharacters, config.Current.ModificationTokenLength)
paste.ModificationToken = modificationToken paste.ModificationToken = modificationToken
err = paste.HashModificationToken() err = paste.HashModificationToken()