132 lines
3.3 KiB
Go
132 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func (server *ApiServer) loadEndpoints() {
|
|
server.engine.GET("/ping", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"message": "pong",
|
|
})
|
|
})
|
|
|
|
// info for user-end html pages
|
|
serverInfo := ServerInfo{
|
|
ClientID: server.conf.ClientID,
|
|
AuthParams: TwitchAuthParams{
|
|
ClientID: server.conf.ClientID,
|
|
ForceVerify: false,
|
|
RedirectURI: server.conf.RedirectURI,
|
|
ResponseType: "code",
|
|
Scope: []string{
|
|
"bits:read",
|
|
"channel:bot",
|
|
"channel:read:goals",
|
|
"channel:read:hype_train",
|
|
"channel:read:polls",
|
|
"channel:manage:polls",
|
|
"channel:read:predictions",
|
|
"channel:manage:predictions",
|
|
"channel:read:redemptions",
|
|
"channel:manage:redemptions",
|
|
"channel:read:vips",
|
|
"channel:moderate",
|
|
"user:bot",
|
|
"user:read:broadcast",
|
|
"user:read:chat",
|
|
"user:read:emotes",
|
|
"user:write:chat",
|
|
},
|
|
State: "", // TODO make this unique per request
|
|
},
|
|
}
|
|
|
|
server.engine.GET("/info", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, serverInfo)
|
|
})
|
|
|
|
server.engine.GET("/auth", func(c *gin.Context) {
|
|
q := c.Request.URL.Query()
|
|
if resp := loadAuthQueryOk(q); resp != nil {
|
|
// ok
|
|
// TODO check state (need state system)
|
|
// TODO POST https://id.twitch.tv/oauth2/token - returns TwitchAuthTokenResp
|
|
// convert expiresIn to time.Time (minus like 15 minutes as a buffer period)
|
|
// UpdateUserAuth()
|
|
// TODO return twitch ok (or err if can't POST)
|
|
} else if resp := loadAuthQueryErr(q); resp != nil {
|
|
// err from twitch
|
|
// TODO check state (need state system)
|
|
// TODO return twitch err
|
|
} else {
|
|
// err in params
|
|
// TODO return param err
|
|
}
|
|
|
|
// TODO auth response from twitch
|
|
// parse args as TwitchAuthRespOk or TwitchAuthRespErr
|
|
// verify state with db and client id with config
|
|
c.JSON(http.StatusOK, serverInfo)
|
|
})
|
|
}
|
|
|
|
type ServerInfo struct {
|
|
ClientID string `json:"client_id"`
|
|
AuthParams TwitchAuthParams `json:"auth_params"`
|
|
}
|
|
|
|
type TwitchAuthParams struct {
|
|
ClientID string `json:"client_id"`
|
|
ForceVerify bool `json:"force_verify"`
|
|
RedirectURI string `json:"redirect_uri"`
|
|
ResponseType string `json:"response_type"`
|
|
Scope []string `json:"scope"`
|
|
State string `json:"state"`
|
|
}
|
|
|
|
func loadAuthQueryOk(query url.Values) *TwitchAuthRespOk {
|
|
if query.Has("code") && query.Has("scope") && query.Has("state") {
|
|
return &TwitchAuthRespOk{
|
|
Code: query.Get("code"),
|
|
Scope: query.Get("scope"),
|
|
State: query.Get("state"),
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func loadAuthQueryErr(query url.Values) *TwitchAuthRespErr {
|
|
if query.Has("error") && query.Has("error_description") && query.Has("state") {
|
|
return &TwitchAuthRespErr{
|
|
Err: query.Get("error"),
|
|
ErrDesc: query.Get("error_description"),
|
|
State: query.Get("state"),
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type TwitchAuthRespOk struct {
|
|
Code string `json:"code"`
|
|
Scope string `json:"scope"`
|
|
State string `json:"state"`
|
|
}
|
|
|
|
type TwitchAuthRespErr struct {
|
|
Err string `json:"error"`
|
|
ErrDesc string `json:"error_description"`
|
|
State string `json:"state"`
|
|
}
|
|
|
|
type TwitchAuthTokenResp struct {
|
|
AccessToken string `json:"access_token"`
|
|
ExpiresIn int `json:"expires_in"`
|
|
RefreshToken string `json:"refresh_token"`
|
|
Scope []string `json:"scope"`
|
|
TokenType string `json:"token_type"`
|
|
}
|