Browse Source

Add db registry of newly created accounts and who invited them

- Resolves: #11
merge-requests/9/head
meskio 3 years ago
parent
commit
3f7cdcf15d
Signed by: meskio
GPG Key ID: 52B8F5AC97A2DA86
  1. 31
      db/account.go
  2. 36
      db/db.go
  3. 28
      db/invite.go
  4. 4
      main.go
  5. 10
      server/add_user.go

31
db/account.go

@ -0,0 +1,31 @@
package db
import (
"time"
)
var (
accountBucket = []byte("account")
)
type account struct {
Host string
CreationDate time.Time
}
// AddAccount stores in the db the account and it's host who invited it
func (db *DB) AddAccount(user string, host string) error {
return db.put(accountBucket, user, account{host, time.Now()})
}
// GetHost that invited the user
func (db *DB) GetHost(user string) (string, error) {
var acc account
err := db.get(accountBucket, user, &acc)
return acc.Host, err
}
// ExpireAccounts older than duration
func (db *DB) ExpireAccounts(duration time.Duration) error {
return db.expire(accountBucket, duration)
}

36
db/db.go

@ -2,6 +2,8 @@ package db
import (
"encoding/json"
"log"
"time"
"go.etcd.io/bbolt"
)
@ -19,12 +21,14 @@ func Init(path string) (*DB, error) {
}
err = bolt.Update(func(tx *bbolt.Tx) error {
_, err := tx.CreateBucketIfNotExists(askSindominanteBucket)
if err != nil {
return err
for _, bucket := range [][]byte{askSindominanteBucket, inviteBucket, accountBucket} {
_, err := tx.CreateBucketIfNotExists(bucket)
if err != nil {
return err
}
}
_, err = tx.CreateBucketIfNotExists(inviteBucket)
return err
return nil
})
if err != nil {
bolt.Close()
@ -72,6 +76,28 @@ func (db *DB) del(bucket []byte, key string) error {
})
}
func (db *DB) expire(bucket []byte, duration time.Duration) error {
var value struct {
CreationDate time.Time
}
return db.bolt.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(bucket)
return b.ForEach(func(k, v []byte) error {
err := json.Unmarshal(v, &value)
if err != nil {
log.Printf("Error unmarshalling %s: %v", string(k), err)
return nil
}
if value.CreationDate.Add(duration).Before(time.Now()) {
return b.Delete(k)
}
return nil
})
})
}
type notFoundError struct{}
func (e notFoundError) Error() string {

28
db/invite.go

@ -1,11 +1,7 @@
package db
import (
"encoding/json"
"log"
"time"
"go.etcd.io/bbolt"
)
var (
@ -29,6 +25,13 @@ func (db *DB) IsInviteValid(code string) bool {
return err == nil
}
// InviteHost returns the user name that created the invite
func (db *DB) InviteHost(code string) (string, error) {
var inv invite
err := db.get(inviteBucket, code, &inv)
return inv.User, err
}
// DelInvite code from the database
func (db *DB) DelInvite(code string) error {
return db.del(inviteBucket, code)
@ -36,20 +39,5 @@ func (db *DB) DelInvite(code string) error {
// ExpireInvites older than duration
func (db *DB) ExpireInvites(duration time.Duration) error {
return db.bolt.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(inviteBucket)
return b.ForEach(func(k, v []byte) error {
var inv invite
err := json.Unmarshal(v, &inv)
if err != nil {
log.Printf("Error unmarshalling invite %s: %v", string(k), err)
return nil
}
if inv.CreationDate.Add(duration).Before(time.Now()) {
return b.Delete(k)
}
return nil
})
})
return db.expire(inviteBucket, duration)
}

4
main.go

@ -16,7 +16,8 @@ import (
)
var (
inviteExpireDuration = time.Hour * 24 * 30
inviteExpireDuration = time.Hour * 24 * 30 // 30 days
accountExpireDuration = time.Hour * 24 * 90 // 90 days
)
func main() {
@ -67,6 +68,7 @@ func main() {
func cleanInvites(ldb *db.DB) {
for {
ldb.ExpireInvites(inviteExpireDuration)
ldb.ExpireAccounts(accountExpireDuration)
time.Sleep(time.Minute * 60)
}
}

10
server/add_user.go

@ -151,6 +151,16 @@ func (s *server) addUserHandler(w http.ResponseWriter, r *http.Request) {
s.errorHandler(w, r)
return
}
host, err := s.db.InviteHost(invite)
if err != nil {
log.Println("Error getting invite host: ", err)
} else {
err = s.db.AddAccount(name, host)
if err != nil {
log.Println("Error adding account: ", err)
}
}
err = s.db.DelInvite(invite)
if err != nil {
log.Println("Error deleting invite: ", err)

Loading…
Cancel
Save