mirror of
https://github.com/ChuckNorrison/LightningTipBot.git
synced 2026-08-13 12:33:14 +02:00
add admin service (#263)
* add admin server + service * string fixes * ban and unban user * add return * ban using admin key * ban reason * remove redundant func call * add http status * add log * anon_id_sha256 (#262) * anon_id_sha256 * refactor sha256 hash to strings package * oops Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com> * add admin server + service * ban and unban user * string fixes * add return * ban using admin key * ban reason * remove redundant func call * add http status * add log Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com> Co-authored-by: LightningTipBot <88730856+LightningTipBot@users.noreply.github.com>
This commit is contained in:
parent
e275b8760a
commit
8f60cb82f3
6 changed files with 113 additions and 23 deletions
16
internal/api/admin/admin.go
Normal file
16
internal/api/admin/admin.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/telegram"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func New(b *telegram.TipBot) Service {
|
||||
return Service{
|
||||
db: b.Database,
|
||||
}
|
||||
}
|
||||
65
internal/api/admin/ban.go
Normal file
65
internal/api/admin/ban.go
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/lnbits"
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (s Service) UnbanUser(w http.ResponseWriter, r *http.Request) {
|
||||
user, err := s.getUserByTelegramId(r)
|
||||
if err != nil {
|
||||
log.Errorf("[ADMIN] could not ban user: %v", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !user.Banned {
|
||||
log.Infof("[ADMIN] user already banned")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user.Banned = false
|
||||
adminSlice := strings.Split(user.Wallet.Adminkey, "_")
|
||||
user.Wallet.Adminkey = adminSlice[len(adminSlice)-1]
|
||||
s.db.Save(user)
|
||||
log.Infof("[ADMIN] Unbanned user (%s)", user.ID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (s Service) BanUser(w http.ResponseWriter, r *http.Request) {
|
||||
user, err := s.getUserByTelegramId(r)
|
||||
if err != nil {
|
||||
log.Errorf("[ADMIN] could not ban user: %v", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if user.Banned {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
log.Infof("[ADMIN] user already banned")
|
||||
return
|
||||
}
|
||||
user.Banned = true
|
||||
if reason := r.URL.Query().Get("reason"); reason != "" {
|
||||
user.Wallet.Adminkey = fmt.Sprintf("%s_%s", reason, user.Wallet.Adminkey)
|
||||
}
|
||||
user.Wallet.Adminkey = fmt.Sprintf("%s_%s", "banned", user.Wallet.Adminkey)
|
||||
s.db.Save(user)
|
||||
log.Infof("[ADMIN] Banned user (%s)", user.ID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (s Service) getUserByTelegramId(r *http.Request) (*lnbits.User, error) {
|
||||
user := &lnbits.User{}
|
||||
v := mux.Vars(r)
|
||||
if v["id"] == "" {
|
||||
return nil, fmt.Errorf("invalid id")
|
||||
}
|
||||
tx := s.db.Where("telegram_id = ? COLLATE NOCASE", v["id"]).First(user)
|
||||
if tx.Error != nil {
|
||||
return nil, tx.Error
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
|
@ -20,9 +20,9 @@ const (
|
|||
StatusOk = "OK"
|
||||
)
|
||||
|
||||
func NewServer() *Server {
|
||||
func NewServer(address string) *Server {
|
||||
srv := &http.Server{
|
||||
Addr: internal.Configuration.Bot.LNURLServerUrl.Host,
|
||||
Addr: address,
|
||||
// Good practice: enforce timeouts for servers you create!
|
||||
WriteTimeout: 15 * time.Second,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
|
|
@ -40,6 +40,9 @@ func NewServer() *Server {
|
|||
func (w *Server) ListenAndServe() {
|
||||
go w.httpServer.ListenAndServe()
|
||||
}
|
||||
func (w *Server) PathPrefix(path string, handler http.Handler) {
|
||||
w.router.PathPrefix(path).Handler(handler)
|
||||
}
|
||||
func (w *Server) AppendRoute(path string, handler func(http.ResponseWriter, *http.Request), methods ...string) {
|
||||
r := w.router.HandleFunc(path, LoggingMiddleware("API", handler))
|
||||
if len(methods) > 0 {
|
||||
|
|
|
|||
|
|
@ -15,17 +15,18 @@ type Client struct {
|
|||
}
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name" gorm:"primaryKey"`
|
||||
Initialized bool `json:"initialized"`
|
||||
Telegram *tb.User `gorm:"embedded;embeddedPrefix:telegram_"`
|
||||
Wallet *Wallet `gorm:"embedded;embeddedPrefix:wallet_"`
|
||||
StateKey UserStateKey `json:"stateKey"`
|
||||
StateData string `json:"stateData"`
|
||||
CreatedAt time.Time `json:"created"`
|
||||
UpdatedAt time.Time `json:"updated"`
|
||||
AnonID string `json:"anon_id"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name" gorm:"primaryKey"`
|
||||
Initialized bool `json:"initialized"`
|
||||
Telegram *tb.User `gorm:"embedded;embeddedPrefix:telegram_"`
|
||||
Wallet *Wallet `gorm:"embedded;embeddedPrefix:wallet_"`
|
||||
StateKey UserStateKey `json:"stateKey"`
|
||||
StateData string `json:"stateData"`
|
||||
CreatedAt time.Time `json:"created"`
|
||||
UpdatedAt time.Time `json:"updated"`
|
||||
AnonID string `json:"anon_id"`
|
||||
AnonIDSha256 string `json:"anon_id_sha256"`
|
||||
Banned bool `json:"banned"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ package mutex
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -18,14 +19,14 @@ func init() {
|
|||
}
|
||||
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(fmt.Sprintf("Current number of locks: %d\nLocks: %+v\nUse /mutex/unlock endpoint to unlock all users", len(mutexMap.Keys()), mutexMap.Keys())))
|
||||
w.Write([]byte(fmt.Sprintf("Current number of locks: %d\nLocks: %+v\nUse /mutex/unlock/{id} endpoint to mutex", len(mutexMap.Keys()), mutexMap.Keys())))
|
||||
}
|
||||
|
||||
func UnlockHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
if m, ok := mutexMap.Get(vars["id"]); ok {
|
||||
m.(*sync.Mutex).Unlock()
|
||||
w.Write([]byte(fmt.Sprintf("Unlocked %s mutexe.\nCurrent number of locks: %d\nLocks: %+v",
|
||||
w.Write([]byte(fmt.Sprintf("Unlocked mutex %s.\nCurrent number of locks: %d\nLocks: %+v",
|
||||
vars["id"], len(mutexMap.Keys()), mutexMap.Keys())))
|
||||
return
|
||||
}
|
||||
|
|
@ -108,6 +109,6 @@ func Unlock(s string) {
|
|||
log.Tracef("[Mutex] Unlocked %s", s)
|
||||
} else {
|
||||
// this should never happen. Mutex should have been in the mutexMap.
|
||||
log.Errorf("[Mutex] ⚠⚠⚠️ Unlock %s not in mutexMap. Skip.", s)
|
||||
log.Errorf("[Mutex] ⚠️⚠️⚠️ Unlock %s not in mutexMap. Skip.", s)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
main.go
18
main.go
|
|
@ -1,11 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/LightningTipBot/LightningTipBot/internal"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/api"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/api/admin"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/lndhub"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/lnurl"
|
||||
"github.com/LightningTipBot/LightningTipBot/internal/runtime/mutex"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ func startApiServer(bot *telegram.TipBot) {
|
|||
// start internal webhook server
|
||||
webhook.NewServer(bot)
|
||||
// start external api server
|
||||
s := api.NewServer()
|
||||
s := api.NewServer(internal.Configuration.Bot.LNURLServerUrl.Host)
|
||||
|
||||
// append lnurl handler functions
|
||||
lnUrl := lnurl.New(bot)
|
||||
|
|
@ -53,11 +54,14 @@ func startApiServer(bot *telegram.TipBot) {
|
|||
s.AppendRoute(`/lndhub/ext`, hub.Handle)
|
||||
|
||||
// start internal admin server
|
||||
router := mux.NewRouter()
|
||||
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
|
||||
router.Handle("/mutex", http.HandlerFunc(mutex.ServeHTTP))
|
||||
router.Handle("/mutex/unlock/{id}", http.HandlerFunc(mutex.UnlockHTTP))
|
||||
go http.ListenAndServe("0.0.0.0:6060", router)
|
||||
adminService := admin.New(bot)
|
||||
internalAdminServer := api.NewServer("0.0.0.0:6060")
|
||||
internalAdminServer.AppendRoute("/mutex", mutex.ServeHTTP)
|
||||
internalAdminServer.AppendRoute("/mutex/unlock/{id}", mutex.UnlockHTTP)
|
||||
internalAdminServer.AppendRoute("/admin/ban/{id}", adminService.BanUser)
|
||||
internalAdminServer.AppendRoute("/admin/unban/{id}", adminService.UnbanUser)
|
||||
internalAdminServer.PathPrefix("/debug/pprof/", http.DefaultServeMux)
|
||||
|
||||
}
|
||||
|
||||
func withRecovery() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue