+92
cmd/admin/main.go
+92
cmd/admin/main.go
···
10
10
"time"
11
11
12
12
"github.com/bluesky-social/indigo/atproto/crypto"
13
+
"github.com/bluesky-social/indigo/atproto/syntax"
14
+
"github.com/haileyok/cocoon/internal/helpers"
13
15
"github.com/lestrrat-go/jwx/v2/jwk"
14
16
"github.com/urfave/cli/v2"
17
+
"golang.org/x/crypto/bcrypt"
18
+
"gorm.io/driver/sqlite"
19
+
"gorm.io/gorm"
15
20
)
16
21
17
22
func main() {
···
20
25
Commands: cli.Commands{
21
26
runCreateRotationKey,
22
27
runCreatePrivateJwk,
28
+
runCreateInviteCode,
29
+
runResetPassword,
23
30
},
24
31
ErrWriter: os.Stdout,
25
32
}
···
92
99
return nil
93
100
},
94
101
}
102
+
103
+
var runCreateInviteCode = &cli.Command{
104
+
Name: "create-invite-code",
105
+
Usage: "creates an invite code",
106
+
Flags: []cli.Flag{
107
+
&cli.StringFlag{
108
+
Name: "for",
109
+
Usage: "optional did to assign the invite code to",
110
+
},
111
+
&cli.IntFlag{
112
+
Name: "uses",
113
+
Usage: "number of times the invite code can be used",
114
+
Value: 1,
115
+
},
116
+
},
117
+
Action: func(cmd *cli.Context) error {
118
+
db, err := newDb()
119
+
if err != nil {
120
+
return err
121
+
}
122
+
123
+
forDid := "did:plc:123"
124
+
if cmd.String("for") != "" {
125
+
did, err := syntax.ParseDID(cmd.String("for"))
126
+
if err != nil {
127
+
return err
128
+
}
129
+
130
+
forDid = did.String()
131
+
}
132
+
133
+
uses := cmd.Int("uses")
134
+
135
+
code := fmt.Sprintf("%s-%s", helpers.RandomVarchar(8), helpers.RandomVarchar(8))
136
+
137
+
if err := db.Exec("INSERT INTO invite_codes (did, code, remaining_use_count) VALUES (?, ?, ?)", forDid, code, uses).Error; err != nil {
138
+
return err
139
+
}
140
+
141
+
fmt.Printf("New invite code created with %d uses: %s\n", uses, code)
142
+
143
+
return nil
144
+
},
145
+
}
146
+
147
+
var runResetPassword = &cli.Command{
148
+
Name: "reset-password",
149
+
Usage: "resets a password",
150
+
Flags: []cli.Flag{
151
+
&cli.StringFlag{
152
+
Name: "did",
153
+
Usage: "did of the user who's password you want to reset",
154
+
},
155
+
},
156
+
Action: func(cmd *cli.Context) error {
157
+
db, err := newDb()
158
+
if err != nil {
159
+
return err
160
+
}
161
+
162
+
didStr := cmd.String("did")
163
+
did, err := syntax.ParseDID(didStr)
164
+
if err != nil {
165
+
return err
166
+
}
167
+
168
+
newPass := fmt.Sprintf("%s-%s", helpers.RandomVarchar(12), helpers.RandomVarchar(12))
169
+
hashed, err := bcrypt.GenerateFromPassword([]byte(newPass), 10)
170
+
if err != nil {
171
+
return err
172
+
}
173
+
174
+
if err := db.Exec("UPDATE repos SET password = ? WHERE did = ?", hashed, did.String()).Error; err != nil {
175
+
return err
176
+
}
177
+
178
+
fmt.Printf("Password for %s has been reset to: %s", did.String(), newPass)
179
+
180
+
return nil
181
+
},
182
+
}
183
+
184
+
func newDb() (*gorm.DB, error) {
185
+
return gorm.Open(sqlite.Open("cocoon.db"), &gorm.Config{})
186
+
}
+15
-1
internal/helpers/helpers.go
+15
-1
internal/helpers/helpers.go
···
1
1
package helpers
2
2
3
-
import "github.com/labstack/echo/v4"
3
+
import (
4
+
"math/rand"
5
+
6
+
"github.com/labstack/echo/v4"
7
+
)
8
+
9
+
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
4
10
5
11
func InputError(e echo.Context, custom *string) error {
6
12
msg := "InvalidRequest"
···
23
29
"error": msg,
24
30
})
25
31
}
32
+
33
+
func RandomVarchar(length int) string {
34
+
b := make([]rune, length)
35
+
for i := range b {
36
+
b[i] = letters[rand.Intn(len(letters))]
37
+
}
38
+
return string(b)
39
+
}