190 lines
3.6 KiB
Go
190 lines
3.6 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
)
|
|
|
|
type AddUserReq struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
type AddUserRsp struct {
|
|
ID int `json:"id"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
func AddUser(w http.ResponseWriter, r *http.Request) {
|
|
log.Println("AddUser called")
|
|
req, err := ReadBody[AddUserReq](r)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
if !CheckToken(r) {
|
|
WriteError(w, errors.New("token required"))
|
|
return
|
|
}
|
|
|
|
provider, err := LoadProvider()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
err = provider.AddUser(req.Username, req.Password)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
err = provider.Save()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
}
|
|
|
|
user, err := provider.GetUser(req.Password)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
WriteResponseCode(w, user, http.StatusCreated)
|
|
}
|
|
|
|
type DeleteUserReq struct {
|
|
ID int `json:"id"`
|
|
}
|
|
|
|
func DeleteUser(w http.ResponseWriter, r *http.Request) {
|
|
if !CheckToken(r) {
|
|
WriteError(w, errors.New("token required"))
|
|
return
|
|
}
|
|
req, err := ReadBody[DeleteUserReq](r)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
provider, err := LoadProvider()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
err = provider.DeleteUser(req.ID)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
err = provider.Save()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func AllUsers(w http.ResponseWriter, r *http.Request) {
|
|
fmt.Println("AllUsers called")
|
|
if !CheckToken(r) {
|
|
WriteError(w, errors.New("invalid token"))
|
|
return
|
|
}
|
|
|
|
provider, err := LoadProvider()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
WriteResponse(w, provider)
|
|
}
|
|
|
|
type GetConnectURLReq struct {
|
|
ID int `json:"id"`
|
|
Pass string `json:"pass"`
|
|
}
|
|
|
|
func GetUserURL(w http.ResponseWriter, r *http.Request) {
|
|
req, err := ReadBody[GetConnectURLReq](r)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
|
|
provider, err := LoadProvider()
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
user, err := provider.GetById(req.ID)
|
|
if err != nil {
|
|
WriteError(w, err)
|
|
return
|
|
}
|
|
if user.Password != req.Pass {
|
|
WriteError(w, errors.New("invalid password"))
|
|
return
|
|
}
|
|
|
|
urlTemplate := "hysteria2://%s@%s:%s?obfs=salamander&obfs-password=%s&type=hysteria&mport&security=tls&sni=%s&alpn=h3&fp=chrome&allowInsecure=0#%s"
|
|
authString := encodeURL(user)
|
|
u := fmt.Sprintf(urlTemplate, authString, cfg.Host, cfg.Port, cfg.ObfsPassword, cfg.SNI, formatConfigName(cfg.NameFormat, user))
|
|
WriteResponse(w, u)
|
|
}
|
|
|
|
type AuthReq struct {
|
|
Addr string `json:"addr"`
|
|
Auth string `json:"auth"`
|
|
Tx int `json:"tx"`
|
|
}
|
|
type AuthRsp struct {
|
|
Ok bool `json:"ok"`
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
func DoAuth(w http.ResponseWriter, r *http.Request) {
|
|
data, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
req := new(AuthReq)
|
|
if err := json.Unmarshal(data, req); err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
log.Println(err)
|
|
return
|
|
}
|
|
log.Printf("New auth request from %s, data %s", req.Addr, string(data))
|
|
|
|
reqUser, err := decodeURL(req.Auth)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
provider, err := LoadProvider()
|
|
if err != nil {
|
|
log.Println(err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
user, err := provider.GetUser(reqUser.Password)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
res := &AuthRsp{true, user.Username}
|
|
err = json.NewEncoder(w).Encode(res)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
} else {
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
}
|