hello world
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.env
|
||||
.vscode
|
||||
.DS_Store
|
||||
aaaa
|
||||
34
discord/get.go
Normal file
34
discord/get.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package discord
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func getDiscordUser(token string) User {
|
||||
req, err := http.NewRequest("GET", "https://discord.com/api/v19/users/@me", nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "Bot "+token)
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var respObj = User{}
|
||||
err = json.Unmarshal(respBody, &respObj)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return respObj
|
||||
}
|
||||
19
discord/structs.go
Normal file
19
discord/structs.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package discord
|
||||
|
||||
type User struct {
|
||||
Id string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Discriminator string `json:"discriminator"`
|
||||
Avatar string `json:"avatar"`
|
||||
Bot bool `json:"bot"`
|
||||
System bool `json:"system"`
|
||||
Mfa_enabled bool `json:"mfa_enabled"`
|
||||
Banner string `json:"banner"`
|
||||
Accent_color int `json:"accent_color"`
|
||||
Locale string `json:"locale"`
|
||||
Verified bool `json:"verified"`
|
||||
Email string `json:"email"`
|
||||
Flags int `json:"flags"`
|
||||
Premium_type int `json:"premium_type"`
|
||||
Public_flags int `json:"public_flags"`
|
||||
}
|
||||
52
endpoints/authorization.go
Normal file
52
endpoints/authorization.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/storage"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AuthorizationScope int
|
||||
const (
|
||||
AuthorizationScopeNone AuthorizationScope = iota
|
||||
AuthorizationScopeUser
|
||||
AuthorizationScopeBot
|
||||
)
|
||||
|
||||
func getAuthorization(c *gin.Context) (AuthorizationScope, string) {
|
||||
header := c.GetHeader("Authorization")
|
||||
if header == "" {
|
||||
return AuthorizationScopeNone, ""
|
||||
}
|
||||
headerSpl := strings.Split(header, " ")
|
||||
if len(headerSpl) != 2 {
|
||||
return AuthorizationScopeNone, ""
|
||||
}
|
||||
if headerSpl[0] == "Bearer" {
|
||||
if storage.CheckLoginToken(headerSpl[1]) {
|
||||
return AuthorizationScopeUser, headerSpl[1]
|
||||
}
|
||||
}
|
||||
if headerSpl[0] == "Bot" {
|
||||
// TODO check bot token
|
||||
if true {
|
||||
return AuthorizationScopeBot, headerSpl[1]
|
||||
}
|
||||
}
|
||||
return AuthorizationScopeNone, ""
|
||||
|
||||
}
|
||||
|
||||
func isUserAuthorized(c *gin.Context) bool {
|
||||
scope, _ := getAuthorization(c)
|
||||
return scope == AuthorizationScopeUser
|
||||
}
|
||||
|
||||
func userIsAuthorized(c *gin.Context) {
|
||||
if isUserAuthorized(c) {
|
||||
c.Next()
|
||||
} else {
|
||||
c.AbortWithStatus(401)
|
||||
}
|
||||
}
|
||||
32
endpoints/endpoints.go
Normal file
32
endpoints/endpoints.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Run() {
|
||||
r := gin.Default()
|
||||
|
||||
public := r.Group("/")
|
||||
|
||||
public.POST("/login", login) //web login
|
||||
public.POST("/access", func(c *gin.Context) {}) //access token
|
||||
|
||||
private := r.Group("/")
|
||||
private.Use(userIsAuthorized)
|
||||
|
||||
private.POST("/user", user) //change username/password (required before adding bots)
|
||||
|
||||
private.GET("/bots", func(c *gin.Context) {}) //generalized list of bots
|
||||
private.GET("/bot/:bot", func(c *gin.Context) {}) //specific bot
|
||||
private.POST("/bot/", func(c *gin.Context) {}) //add bot given token
|
||||
private.DELETE("/bot/:bot", func(c *gin.Context) {}) //remove bot
|
||||
|
||||
private.GET("/tokens", func(c *gin.Context) {}) //generalized list of tokens
|
||||
private.GET("/token/:token", func(c *gin.Context) {}) //specific token
|
||||
private.POST("/token/", func(c *gin.Context) {}) //new token given bot (so you cant add a token if theres no bots)
|
||||
private.DELETE("/token/:token", func(c *gin.Context) {}) //remove token
|
||||
private.PATCH("/token/:token", func(c *gin.Context) {}) //update token given bot
|
||||
|
||||
r.Run()
|
||||
}
|
||||
34
endpoints/login.go
Normal file
34
endpoints/login.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/storage"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type LoginBody struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
func login(c *gin.Context) {
|
||||
var loginBody LoginBody
|
||||
if err := c.BindJSON(&loginBody); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
loggedIn, token := storage.CheckLogin(loginBody.Username, loginBody.Password)
|
||||
|
||||
if loggedIn {
|
||||
c.JSON(200, gin.H{
|
||||
"token": token,
|
||||
})
|
||||
} else {
|
||||
c.JSON(401, gin.H{
|
||||
"error": "invalid username or password",
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
18
endpoints/user.go
Normal file
18
endpoints/user.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/storage"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func user(c *gin.Context) {
|
||||
var updateLogin LoginBody
|
||||
if err := c.BindJSON(&updateLogin); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
storage.UpdateUsername(updateLogin.Username)
|
||||
storage.UpdatePassword(updateLogin.Password)
|
||||
}
|
||||
29
go.mod
Normal file
29
go.mod
Normal file
@@ -0,0 +1,29 @@
|
||||
module git.zomo.dev/zomo/discord-retokenizer
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.8.1 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||
github.com/go-redis/redis/v9 v9.0.0-rc.2 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
golang.org/x/crypto v0.4.0 // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
95
go.sum
Normal file
95
go.sum
Normal file
@@ -0,0 +1,95 @@
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-redis/redis/v9 v9.0.0-rc.2 h1:IN1eI8AvJJeWHjMW/hlFAv2sAfvTun2DVksDDJ3a6a0=
|
||||
github.com/go-redis/redis/v9 v9.0.0-rc.2/go.mod h1:cgBknjwcBJa2prbnuHH/4k/Mlj4r0pWNV2HBanHujfY=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
32
main.go
Normal file
32
main.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/endpoints"
|
||||
"git.zomo.dev/zomo/discord-retokenizer/storage"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func checkEnv(env string) {
|
||||
if os.Getenv(env) == "" {
|
||||
panic(env + " not set")
|
||||
}
|
||||
}
|
||||
|
||||
func loadEnv() {
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
checkEnv("REDIS_URI")
|
||||
}
|
||||
|
||||
func main() {
|
||||
loadEnv()
|
||||
|
||||
storage.Init()
|
||||
|
||||
endpoints.Run()
|
||||
}
|
||||
103
storage/api.go
Normal file
103
storage/api.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/util"
|
||||
"github.com/go-redis/redis/v9"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func UpdateUsername(username string) {
|
||||
if username != "" {
|
||||
client.Set(ctx, "username", username, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatePassword(password string) {
|
||||
if password != "" {
|
||||
passHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
client.Set(ctx, "password", string(passHash), 0)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckLogin(username string, password string) (bool, string) {
|
||||
if username == "" || password == "" {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
user, err := client.Get(ctx, "username").Result()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pass, err := client.Get(ctx, "password").Result()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if user != username {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(pass), []byte(password))
|
||||
if err != nil {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
return true, createLoginToken()
|
||||
}
|
||||
|
||||
func createLoginToken() string {
|
||||
token := util.GeneratePassword(32)
|
||||
|
||||
member := redis.Z{
|
||||
Score: float64(time.Now().Unix() + 4 * 60 * 60),
|
||||
Member: token,
|
||||
}
|
||||
|
||||
err := client.ZAdd(ctx, "loginTokens", member).Err()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
func CheckLoginToken(token string) bool {
|
||||
|
||||
expired, err := client.ZRangeByScore(ctx, "loginTokens", &redis.ZRangeBy{
|
||||
Min: "-inf",
|
||||
Max: fmt.Sprintf("%d", time.Now().Unix()),
|
||||
}).Result()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, e := range expired {
|
||||
client.ZRem(ctx, "loginTokens", e)
|
||||
}
|
||||
|
||||
current, err := client.ZRangeByScore(ctx, "loginTokens", &redis.ZRangeBy{
|
||||
Min: fmt.Sprintf("%d", time.Now().Unix()),
|
||||
Max: "inf",
|
||||
}).Result()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, c := range current {
|
||||
fmt.Println(c)
|
||||
if c == token {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
71
storage/storage.go
Normal file
71
storage/storage.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"git.zomo.dev/zomo/discord-retokenizer/util"
|
||||
"github.com/go-redis/redis/v9"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
var client *redis.Client = nil
|
||||
|
||||
func initializeRedis() {
|
||||
username := "default"
|
||||
UpdateUsername( username)
|
||||
password := util.GeneratePassword(16)
|
||||
UpdatePassword( password)
|
||||
fmt.Printf("FIRST TIME SETUP\nusername: %s\npassword: %s\n\n\n", username, password)
|
||||
}
|
||||
|
||||
func validateRedis() {
|
||||
if client == nil {
|
||||
panic("Client == nil")
|
||||
}
|
||||
_, err := client.Get(ctx, "username").Result()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
initializeRedis()
|
||||
return
|
||||
}
|
||||
_, err = client.Get(ctx, "password").Result()
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
panic(err)
|
||||
}
|
||||
initializeRedis()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func Init() {
|
||||
redisUri, err := url.Parse(os.Getenv("REDIS_URI"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if redisUri.Scheme != "redis" {
|
||||
panic("redisUri.Scheme != redis")
|
||||
}
|
||||
|
||||
username := redisUri.User.Username()
|
||||
pass, passSet := redisUri.User.Password()
|
||||
|
||||
if !passSet {
|
||||
panic("pass not set")
|
||||
}
|
||||
|
||||
client = redis.NewClient(&redis.Options{
|
||||
Addr: redisUri.Host,
|
||||
Username: username,
|
||||
Password: pass,
|
||||
DB: 0,
|
||||
})
|
||||
|
||||
validateRedis()
|
||||
}
|
||||
29
util/rand.go
Normal file
29
util/rand.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var passwordChars = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-=_+!@#$%^&*()[]{}|;:,.<>/?")
|
||||
func GeneratePassword(length int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
b := make([]rune, length)
|
||||
for i := range b {
|
||||
b[i] = passwordChars[rand.Intn(len(passwordChars))]
|
||||
}
|
||||
|
||||
code := string(b)
|
||||
return code
|
||||
}
|
||||
|
||||
func GenerateToken() string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
b := make([]byte, 32)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return ""
|
||||
}
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
Reference in New Issue
Block a user