An atproto PDS written in Go

add additional admin helpers

Changed files
+107 -1
cmd
admin
internal
helpers
+92
cmd/admin/main.go
···
"time"
"github.com/bluesky-social/indigo/atproto/crypto"
+
"github.com/bluesky-social/indigo/atproto/syntax"
+
"github.com/haileyok/cocoon/internal/helpers"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/urfave/cli/v2"
+
"golang.org/x/crypto/bcrypt"
+
"gorm.io/driver/sqlite"
+
"gorm.io/gorm"
)
func main() {
···
Commands: cli.Commands{
runCreateRotationKey,
runCreatePrivateJwk,
+
runCreateInviteCode,
+
runResetPassword,
},
ErrWriter: os.Stdout,
}
···
return nil
},
}
+
+
var runCreateInviteCode = &cli.Command{
+
Name: "create-invite-code",
+
Usage: "creates an invite code",
+
Flags: []cli.Flag{
+
&cli.StringFlag{
+
Name: "for",
+
Usage: "optional did to assign the invite code to",
+
},
+
&cli.IntFlag{
+
Name: "uses",
+
Usage: "number of times the invite code can be used",
+
Value: 1,
+
},
+
},
+
Action: func(cmd *cli.Context) error {
+
db, err := newDb()
+
if err != nil {
+
return err
+
}
+
+
forDid := "did:plc:123"
+
if cmd.String("for") != "" {
+
did, err := syntax.ParseDID(cmd.String("for"))
+
if err != nil {
+
return err
+
}
+
+
forDid = did.String()
+
}
+
+
uses := cmd.Int("uses")
+
+
code := fmt.Sprintf("%s-%s", helpers.RandomVarchar(8), helpers.RandomVarchar(8))
+
+
if err := db.Exec("INSERT INTO invite_codes (did, code, remaining_use_count) VALUES (?, ?, ?)", forDid, code, uses).Error; err != nil {
+
return err
+
}
+
+
fmt.Printf("New invite code created with %d uses: %s\n", uses, code)
+
+
return nil
+
},
+
}
+
+
var runResetPassword = &cli.Command{
+
Name: "reset-password",
+
Usage: "resets a password",
+
Flags: []cli.Flag{
+
&cli.StringFlag{
+
Name: "did",
+
Usage: "did of the user who's password you want to reset",
+
},
+
},
+
Action: func(cmd *cli.Context) error {
+
db, err := newDb()
+
if err != nil {
+
return err
+
}
+
+
didStr := cmd.String("did")
+
did, err := syntax.ParseDID(didStr)
+
if err != nil {
+
return err
+
}
+
+
newPass := fmt.Sprintf("%s-%s", helpers.RandomVarchar(12), helpers.RandomVarchar(12))
+
hashed, err := bcrypt.GenerateFromPassword([]byte(newPass), 10)
+
if err != nil {
+
return err
+
}
+
+
if err := db.Exec("UPDATE repos SET password = ? WHERE did = ?", hashed, did.String()).Error; err != nil {
+
return err
+
}
+
+
fmt.Printf("Password for %s has been reset to: %s", did.String(), newPass)
+
+
return nil
+
},
+
}
+
+
func newDb() (*gorm.DB, error) {
+
return gorm.Open(sqlite.Open("cocoon.db"), &gorm.Config{})
+
}
+15 -1
internal/helpers/helpers.go
···
package helpers
-
import "github.com/labstack/echo/v4"
+
import (
+
"math/rand"
+
+
"github.com/labstack/echo/v4"
+
)
+
+
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
func InputError(e echo.Context, custom *string) error {
msg := "InvalidRequest"
···
"error": msg,
})
}
+
+
func RandomVarchar(length int) string {
+
b := make([]rune, length)
+
for i := range b {
+
b[i] = letters[rand.Intn(len(letters))]
+
}
+
return string(b)
+
}