github.com/imgk/caddy-trojan@v0.0.0-20221206043256-2631719e16c8/admin/admin.go (about) 1 package admin 2 3 import ( 4 "encoding/json" 5 "errors" 6 "io" 7 "net/http" 8 9 "github.com/caddyserver/caddy/v2" 10 11 "github.com/imgk/caddy-trojan/app" 12 ) 13 14 func init() { 15 caddy.RegisterModule(Admin{}) 16 } 17 18 // Admin is ... 19 type Admin struct { 20 // Upstream is ... 21 Upstream app.Upstream 22 } 23 24 // CaddyModule returns the Caddy module information. 25 func (Admin) CaddyModule() caddy.ModuleInfo { 26 return caddy.ModuleInfo{ 27 ID: "admin.api.trojan", 28 New: func() caddy.Module { return new(Admin) }, 29 } 30 } 31 32 // Provision is ... 33 func (al *Admin) Provision(ctx caddy.Context) error { 34 if !ctx.AppIsConfigured(app.CaddyAppID) { 35 return nil 36 } 37 mod, err := ctx.App(app.CaddyAppID) 38 if err != nil { 39 return err 40 } 41 app := mod.(*app.App) 42 al.Upstream = app.Upstream() 43 return nil 44 } 45 46 // Routes returns a route for the /trojan/* endpoint. 47 func (al *Admin) Routes() []caddy.AdminRoute { 48 return []caddy.AdminRoute{ 49 { 50 Pattern: "/trojan/users", 51 Handler: caddy.AdminHandlerFunc(al.GetUsers), 52 }, 53 { 54 Pattern: "/trojan/users/add", 55 Handler: caddy.AdminHandlerFunc(al.AddUser), 56 }, 57 { 58 Pattern: "/trojan/users/delete", 59 Handler: caddy.AdminHandlerFunc(al.DeleteUser), 60 }, 61 } 62 } 63 64 // GetUsers is ... 65 func (al *Admin) GetUsers(w http.ResponseWriter, r *http.Request) error { 66 if al.Upstream == nil { 67 return nil 68 } 69 70 if r.Method != http.MethodGet { 71 return errors.New("get trojan user method error") 72 } 73 74 type User struct { 75 Key string `json:"key"` 76 Up int64 `json:"up"` 77 Down int64 `json:"down"` 78 } 79 80 users := make([]User, 0) 81 al.Upstream.Range(func(key string, up, down int64) { 82 users = append(users, User{Key: key, Up: up, Down: down}) 83 }) 84 85 w.WriteHeader(http.StatusOK) 86 json.NewEncoder(w).Encode(users) 87 return nil 88 } 89 90 // AddUser is ... 91 func (al *Admin) AddUser(w http.ResponseWriter, r *http.Request) error { 92 if al.Upstream == nil { 93 return nil 94 } 95 96 if r.Method != http.MethodPost { 97 return errors.New("add trojan user method error") 98 } 99 100 type User struct { 101 Password string `json:"password,omitempty"` 102 } 103 104 b, err := io.ReadAll(r.Body) 105 if err != nil { 106 return err 107 } 108 user := User{} 109 if err := json.Unmarshal(b, &user); err != nil { 110 return err 111 } 112 if user.Password != "" { 113 al.Upstream.Add(user.Password) 114 } 115 116 w.WriteHeader(http.StatusOK) 117 return nil 118 } 119 120 // DeleteUser is ... 121 func (al *Admin) DeleteUser(w http.ResponseWriter, r *http.Request) error { 122 if al.Upstream == nil { 123 return nil 124 } 125 126 if r.Method != http.MethodDelete { 127 return errors.New("delete trojan user method error") 128 } 129 130 type User struct { 131 Password string `json:"password,omitempty"` 132 } 133 134 b, err := io.ReadAll(r.Body) 135 if err != nil { 136 return err 137 } 138 user := User{} 139 if err := json.Unmarshal(b, &user); err != nil { 140 return err 141 } 142 if user.Password != "" { 143 al.Upstream.Delete(user.Password) 144 } 145 146 w.WriteHeader(http.StatusOK) 147 return nil 148 } 149 150 // Interface guards 151 var ( 152 _ caddy.AdminRouter = (*Admin)(nil) 153 _ caddy.Provisioner = (*Admin)(nil) 154 )