initial commit on github
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/getsentry/sentry-go"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var lpServer *LongPollServer
|
||||
|
||||
func RegisterRouters(r *mux.Router) {
|
||||
sub := r.PathPrefix("/v1").Subrouter()
|
||||
|
||||
lpServer = InitLongPollServer()
|
||||
|
||||
sub.Use(apiMiddleware)
|
||||
sub.Use(LimitMiddleware)
|
||||
go CleanupVisitors()
|
||||
sub.Use(JWTMiddleware)
|
||||
|
||||
sub.HandleFunc("/version", func(w http.ResponseWriter, _ *http.Request) {
|
||||
Response(w, nil, map[string]string{
|
||||
"version": config.Version,
|
||||
"build": strconv.Itoa(int(config.Build)),
|
||||
})
|
||||
})
|
||||
|
||||
RegisterAuthRoutes(sub)
|
||||
RegisterUsersRoutes(sub)
|
||||
RegisterNovelsRoutes(sub)
|
||||
RegisterCharactersRoutes(sub)
|
||||
RegisterGenresRoutes(sub)
|
||||
RegisterGamesRoutes(sub)
|
||||
RegisterClubRoutes(sub)
|
||||
RegisterGroupsRoutes(sub)
|
||||
RegisterNewsRoutes(sub)
|
||||
RegisterTokensRouter(sub)
|
||||
RegisterLongPollRoutes(sub)
|
||||
|
||||
if config.Debug {
|
||||
err := sub.Walk(func(route *mux.Route, _ *mux.Router, _ []*mux.Route) error {
|
||||
path, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("loading path %s\n", path)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Response(w http.ResponseWriter, err error, data interface{}) {
|
||||
const baseResponse = `{"error":false,"data":%v}`
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound.Ferror(w)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
}
|
||||
} else {
|
||||
j, err := json.Marshal(&data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, baseResponse, string(j))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ResponsePagination(w http.ResponseWriter, err error, data interface{}, pagination interface{}) {
|
||||
const baseResponse = `{"error":false,"pagination":%v,"data":%v}`
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound.Ferror(w)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Error(w, err)
|
||||
}
|
||||
} else {
|
||||
jsonData, err := json.Marshal(&data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPagination, err := json.Marshal(&pagination)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, baseResponse, string(jsonPagination), string(jsonData))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RawError(w http.ResponseWriter, e string) {
|
||||
const baseError = `{"error":true,"error_data":{"code":-1,"text":"%v"}}`
|
||||
|
||||
_, err := fmt.Fprintf(w, baseError, strings.ReplaceAll(e, `"`, `\"`))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Error(w http.ResponseWriter, e error) {
|
||||
const baseError = `{"error":true,"error_data":{"code":-1,"text":"%v"}}`
|
||||
|
||||
_, err := fmt.Fprintf(w, baseError, strings.ReplaceAll(e.Error(), `"`, `\"`))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
}
|
||||
}
|
||||
|
||||
func JSON(w http.ResponseWriter, data string) {
|
||||
_, err := fmt.Fprint(w, data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sentry.CaptureException(err)
|
||||
}
|
||||
}
|
||||
|
||||
func ReadBody(r *http.Request) ([]byte, error) {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = r.Body.Close()
|
||||
return body, err
|
||||
}
|
||||
|
||||
func MD5(s string) string {
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(s))
|
||||
return hex.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
func GetCurrentUserID(r *http.Request) (uint64, error) {
|
||||
tokenCookie, err := r.Cookie("token")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
token, err := jwt.Parse(tokenCookie.Value, func(token *jwt.Token) (interface{}, error) {
|
||||
if token.Method != jwt.SigningMethodHS256 {
|
||||
return nil, fmt.Errorf("invalid singning method: %s", token.Method)
|
||||
}
|
||||
return []byte(privateConfig.AuthTokenSecret), nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
claims := token.Claims.(jwt.MapClaims)
|
||||
id := int(claims["id"].(float64))
|
||||
return uint64(id), nil
|
||||
}
|
||||
|
||||
func apiMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Dev") == "1" {
|
||||
w.Header().Add("Access-Control-Allow-Origin", config.DevFrontendUrl)
|
||||
} else {
|
||||
w.Header().Add("Access-Control-Allow-Origin", config.FrontendUrl)
|
||||
}
|
||||
w.Header().Add("Access-Control-Allow-Credentials", "true")
|
||||
w.Header().Add("Content-Type", "application/json; charset=utf-8")
|
||||
//w.Header().Add("Cache-Control", "max-age=60")
|
||||
|
||||
if r.Method == http.MethodOptions {
|
||||
w.Header().Add("Access-Control-Allow-Headers", "Content-Type, Date, Content-Length, Location, dev")
|
||||
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
||||
return
|
||||
}
|
||||
|
||||
if database == nil {
|
||||
log.Println("db not initialized")
|
||||
return
|
||||
}
|
||||
err := database.Ping()
|
||||
if err != nil && strings.Contains(err.Error(), "broken pipe") {
|
||||
ConnectToDB()
|
||||
log.Println("connection to db reopened")
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user