Add setup wiki for discord oauth + nearly finish web interface
This commit is contained in:
parent
0dc1423b9d
commit
8e198dcdd7
|
@ -24,6 +24,7 @@ type CS struct {
|
||||||
API struct {
|
API struct {
|
||||||
Host string
|
Host string
|
||||||
Port string
|
Port string
|
||||||
|
FrontendPort string
|
||||||
}
|
}
|
||||||
JWT struct {
|
JWT struct {
|
||||||
Secret string
|
Secret string
|
||||||
|
@ -91,6 +92,11 @@ func LoadConfig(file []byte) {
|
||||||
panic("API Port is empty")
|
panic("API Port is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Config.API.FrontendPort = cfg.Section("api").Key("frontend_port").String()
|
||||||
|
if Config.API.FrontendPort == "" {
|
||||||
|
Config.API.FrontendPort = Config.API.Port
|
||||||
|
}
|
||||||
|
|
||||||
Config.JWT.Secret = cfg.Section("jwt").Key("secret").String()
|
Config.JWT.Secret = cfg.Section("jwt").Key("secret").String()
|
||||||
if Config.JWT.Secret == "" {
|
if Config.JWT.Secret == "" {
|
||||||
panic("JWT Secret is empty")
|
panic("JWT Secret is empty")
|
||||||
|
|
11
aid/fiber.go
11
aid/fiber.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||||
)
|
)
|
||||||
|
@ -22,10 +23,8 @@ func FiberLimiter() fiber.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
func FiberCors() fiber.Handler {
|
func FiberCors() fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return cors.New(cors.Config{
|
||||||
c.Set("Access-Control-Allow-Origin", "*")
|
AllowOrigins: "*",
|
||||||
c.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
AllowHeaders: "Origin, Content-Type, Accept, Authorization, X-Requested-With",
|
||||||
c.Set("Access-Control-Allow-Headers", "Content-Type, Authorization, Origin, Accept, X-Requested-With")
|
})
|
||||||
return c.Next()
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -7,17 +7,17 @@ type="postgres"
|
||||||
drop=false
|
drop=false
|
||||||
|
|
||||||
[discord]
|
[discord]
|
||||||
; discord oauth2 client id
|
; discord id of the bot
|
||||||
id="1234567890..."
|
id="1234567890..."
|
||||||
; discord oauth2 client secret
|
; oauth2 client secret
|
||||||
secret="abcdefg..."
|
secret="abcdefg..."
|
||||||
; discord bot token
|
; discord bot token
|
||||||
token="OTK...."
|
token="OTK...."
|
||||||
|
|
||||||
[output]
|
[output]
|
||||||
; level of logging
|
; level of logging
|
||||||
; info = everything
|
; info = backend logs
|
||||||
; time = only time taken
|
; time = backend logs + time taken for database queries
|
||||||
; prod = only errors
|
; prod = only errors
|
||||||
level="info"
|
level="info"
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,87 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
|
p "github.com/ectrc/snow/person"
|
||||||
|
"github.com/ectrc/snow/storage"
|
||||||
|
|
||||||
|
"github.com/goccy/go-json"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetDiscordOAuthURL(c *fiber.Ctx) error {
|
func GetDiscordOAuthURL(c *fiber.Ctx) error {
|
||||||
return c.Status(200).SendString("https://discord.com/api/oauth2/authorize?client_id="+ aid.Config.Discord.ID +"&redirect_uri="+ url.QueryEscape(aid.Config.API.Host + aid.Config.API.Port +"/snow/discord/callback") + "&response_type=code&scope=identify")
|
code := c.Query("code")
|
||||||
|
if code == "" {
|
||||||
|
return c.Status(200).SendString("https://discord.com/oauth2/authorize?client_id="+ aid.Config.Discord.ID +"&redirect_uri="+ url.QueryEscape(aid.Config.API.Host + aid.Config.API.Port +"/snow/discord") + "&response_type=code&scope=identify")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
|
||||||
|
oauthRequest, err := client.PostForm("https://discord.com/api/v10/oauth2/token", url.Values{
|
||||||
|
"client_id": {aid.Config.Discord.ID},
|
||||||
|
"client_secret": {aid.Config.Discord.Secret},
|
||||||
|
"grant_type": {"authorization_code"},
|
||||||
|
"code": {code},
|
||||||
|
"redirect_uri": {aid.Config.API.Host + aid.Config.API.Port +"/snow/discord"},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
|
var body struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
RenewToken string `json:"refresh_token"`
|
||||||
|
}
|
||||||
|
err = json.NewDecoder(oauthRequest.Body).Decode(&body)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
|
userRequest, err := http.NewRequest("GET", "https://discord.com/api/v10/users/@me", nil)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
|
||||||
|
}
|
||||||
|
userRequest.Header.Set("Authorization", "Bearer " + body.AccessToken)
|
||||||
|
|
||||||
|
userResponse, err := client.Do(userRequest)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
|
var user struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
}
|
||||||
|
err = json.NewDecoder(userResponse.Body).Decode(&user)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
|
||||||
|
}
|
||||||
|
|
||||||
|
person := p.FindByDiscord(user.ID)
|
||||||
|
if person == nil {
|
||||||
|
return c.Status(404).JSON(aid.ErrorNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
person.Discord.AccessToken = body.AccessToken
|
||||||
|
person.Discord.RefreshToken = body.RenewToken
|
||||||
|
storage.Repo.SaveDiscordPerson(person.Discord)
|
||||||
|
|
||||||
|
access, err := aid.JWTSign(aid.JSON{
|
||||||
|
"snow_id": person.ID, // custom
|
||||||
|
"frontend": true,
|
||||||
|
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(aid.ErrorInternalServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Cookie(&fiber.Cookie{
|
||||||
|
Name: "access_token",
|
||||||
|
Value: access,
|
||||||
|
})
|
||||||
|
return c.Redirect(aid.Config.API.Host + aid.Config.API.FrontendPort + "/attempt")
|
||||||
}
|
}
|
1
main.go
1
main.go
|
@ -120,6 +120,7 @@ func main() {
|
||||||
|
|
||||||
player := snow.Group("/player")
|
player := snow.Group("/player")
|
||||||
player.Use(handlers.FrontendMiddleware)
|
player.Use(handlers.FrontendMiddleware)
|
||||||
|
player.Post("/", handlers.AnyNoContent)
|
||||||
player.Get("/locker", handlers.GetPlayerLocker)
|
player.Get("/locker", handlers.GetPlayerLocker)
|
||||||
|
|
||||||
r.Hooks().OnListen(func(ld fiber.ListenData) error {
|
r.Hooks().OnListen(func(ld fiber.ListenData) error {
|
||||||
|
|
|
@ -65,6 +65,20 @@ func (m *PersonsCache) GetPersonByDisplay(displayName string) *Person {
|
||||||
return person
|
return person
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *PersonsCache) GetPersonByDiscordID(discordId string) *Person {
|
||||||
|
var person *Person
|
||||||
|
m.RangeEntry(func(key string, value *CacheEntry) bool {
|
||||||
|
if value.Entry.Discord.ID == discordId {
|
||||||
|
person = value.Entry
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
return person
|
||||||
|
}
|
||||||
|
|
||||||
func (m *PersonsCache) SavePerson(p *Person) {
|
func (m *PersonsCache) SavePerson(p *Person) {
|
||||||
m.Store(p.ID, &CacheEntry{
|
m.Store(p.ID, &CacheEntry{
|
||||||
Entry: p,
|
Entry: p,
|
||||||
|
|
|
@ -149,7 +149,6 @@ func (l *Loadout) GetAttribute(attribute string) interface{} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch attribute {
|
switch attribute {
|
||||||
case "locker_name":
|
case "locker_name":
|
||||||
return l.LockerName
|
return l.LockerName
|
||||||
|
|
|
@ -15,6 +15,7 @@ type Person struct {
|
||||||
Profile0Profile *Profile
|
Profile0Profile *Profile
|
||||||
CollectionsProfile *Profile
|
CollectionsProfile *Profile
|
||||||
CreativeProfile *Profile
|
CreativeProfile *Profile
|
||||||
|
Discord *storage.DB_DiscordPerson
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
|
@ -59,16 +60,34 @@ func FindByDisplay(displayName string) *Person {
|
||||||
cache = NewPersonsCacheMutex()
|
cache = NewPersonsCacheMutex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cachedPerson := cache.GetPersonByDisplay(displayName)
|
||||||
|
if cachedPerson != nil {
|
||||||
|
return cachedPerson
|
||||||
|
}
|
||||||
|
|
||||||
person := storage.Repo.GetPersonByDisplayFromDB(displayName)
|
person := storage.Repo.GetPersonByDisplayFromDB(displayName)
|
||||||
if person == nil {
|
if person == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedPerson := cache.GetPerson(person.ID)
|
return findHelper(person)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindByDiscord(discordId string) *Person {
|
||||||
|
if cache == nil {
|
||||||
|
cache = NewPersonsCacheMutex()
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedPerson := cache.GetPersonByDiscordID(discordId)
|
||||||
if cachedPerson != nil {
|
if cachedPerson != nil {
|
||||||
return cachedPerson
|
return cachedPerson
|
||||||
}
|
}
|
||||||
|
|
||||||
|
person := storage.Repo.GetPersonByDiscordIDFromDB(discordId)
|
||||||
|
if person == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return findHelper(person)
|
return findHelper(person)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +141,7 @@ func findHelper(databasePerson *storage.DB_Person) *Person {
|
||||||
Profile0Profile: profile0,
|
Profile0Profile: profile0,
|
||||||
CollectionsProfile: collectionsProfile,
|
CollectionsProfile: collectionsProfile,
|
||||||
CreativeProfile: creativeProfile,
|
CreativeProfile: creativeProfile,
|
||||||
|
Discord: &databasePerson.Discord,
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.SavePerson(person)
|
cache.SavePerson(person)
|
||||||
|
@ -182,6 +202,8 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
||||||
DisplayName: p.DisplayName,
|
DisplayName: p.DisplayName,
|
||||||
Profiles: []storage.DB_Profile{},
|
Profiles: []storage.DB_Profile{},
|
||||||
AccessKey: p.AccessKey,
|
AccessKey: p.AccessKey,
|
||||||
|
Discord: *p.Discord,
|
||||||
|
DiscordID: p.Discord.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
profilesToConvert := map[string]*Profile{
|
profilesToConvert := map[string]*Profile{
|
||||||
|
@ -260,5 +282,6 @@ func (p *Person) Snapshot() *PersonSnapshot {
|
||||||
Profile0Profile: *p.Profile0Profile.Snapshot(),
|
Profile0Profile: *p.Profile0Profile.Snapshot(),
|
||||||
CollectionsProfile: *p.CollectionsProfile.Snapshot(),
|
CollectionsProfile: *p.CollectionsProfile.Snapshot(),
|
||||||
CreativeProfile: *p.CreativeProfile.Snapshot(),
|
CreativeProfile: *p.CreativeProfile.Snapshot(),
|
||||||
|
Discord: *p.Discord,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package person
|
package person
|
||||||
|
|
||||||
|
import "github.com/ectrc/snow/storage"
|
||||||
|
|
||||||
type PersonSnapshot struct {
|
type PersonSnapshot struct {
|
||||||
ID string
|
ID string
|
||||||
DisplayName string
|
DisplayName string
|
||||||
|
@ -9,6 +11,7 @@ type PersonSnapshot struct {
|
||||||
Profile0Profile ProfileSnapshot
|
Profile0Profile ProfileSnapshot
|
||||||
CollectionsProfile ProfileSnapshot
|
CollectionsProfile ProfileSnapshot
|
||||||
CreativeProfile ProfileSnapshot
|
CreativeProfile ProfileSnapshot
|
||||||
|
Discord storage.DB_DiscordPerson
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProfileSnapshot struct {
|
type ProfileSnapshot struct {
|
||||||
|
|
|
@ -12,7 +12,7 @@ type PostgresStorage struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostgresStorage() *PostgresStorage {
|
func NewPostgresStorage() *PostgresStorage {
|
||||||
l := logger.Default.LogMode(logger.Silent)
|
l := logger.Default
|
||||||
if aid.Config.Output.Level == "time" {
|
if aid.Config.Output.Level == "time" {
|
||||||
l = logger.Default.LogMode(logger.Info)
|
l = logger.Default.LogMode(logger.Info)
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ func (s *PostgresStorage) MigrateAll() {
|
||||||
s.Migrate(&DB_Loot{}, "Loot")
|
s.Migrate(&DB_Loot{}, "Loot")
|
||||||
s.Migrate(&DB_VariantChannel{}, "Variants")
|
s.Migrate(&DB_VariantChannel{}, "Variants")
|
||||||
s.Migrate(&DB_PAttribute{}, "Attributes")
|
s.Migrate(&DB_PAttribute{}, "Attributes")
|
||||||
|
s.Migrate(&DB_TemporaryCode{}, "Exchange")
|
||||||
|
s.Migrate(&DB_DiscordPerson{}, "Discord")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DropTables() {
|
func (s *PostgresStorage) DropTables() {
|
||||||
|
@ -52,6 +54,7 @@ func (s *PostgresStorage) DropTables() {
|
||||||
func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
||||||
var dbPerson DB_Person
|
var dbPerson DB_Person
|
||||||
s.Postgres.
|
s.Postgres.
|
||||||
|
Model(&DB_Person{}).
|
||||||
Preload("Profiles").
|
Preload("Profiles").
|
||||||
Preload("Profiles.Loadouts").
|
Preload("Profiles.Loadouts").
|
||||||
Preload("Profiles.Items.Variants").
|
Preload("Profiles.Items.Variants").
|
||||||
|
@ -60,6 +63,7 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
||||||
Preload("Profiles.Items").
|
Preload("Profiles.Items").
|
||||||
Preload("Profiles.Gifts").
|
Preload("Profiles.Gifts").
|
||||||
Preload("Profiles.Quests").
|
Preload("Profiles.Quests").
|
||||||
|
Preload("Discord").
|
||||||
Where("id = ?", personId).
|
Where("id = ?", personId).
|
||||||
Find(&dbPerson)
|
Find(&dbPerson)
|
||||||
|
|
||||||
|
@ -73,6 +77,7 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
||||||
func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
||||||
var dbPerson DB_Person
|
var dbPerson DB_Person
|
||||||
s.Postgres.
|
s.Postgres.
|
||||||
|
Model(&DB_Person{}).
|
||||||
Preload("Profiles").
|
Preload("Profiles").
|
||||||
Preload("Profiles.Loadouts").
|
Preload("Profiles.Loadouts").
|
||||||
Preload("Profiles.Items.Variants").
|
Preload("Profiles.Items.Variants").
|
||||||
|
@ -81,6 +86,7 @@ func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
||||||
Preload("Profiles.Items").
|
Preload("Profiles.Items").
|
||||||
Preload("Profiles.Gifts").
|
Preload("Profiles.Gifts").
|
||||||
Preload("Profiles.Quests").
|
Preload("Profiles.Quests").
|
||||||
|
Preload("Discord").
|
||||||
Where("display_name = ?", displayName).
|
Where("display_name = ?", displayName).
|
||||||
Find(&dbPerson)
|
Find(&dbPerson)
|
||||||
|
|
||||||
|
@ -91,10 +97,22 @@ func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
||||||
return &dbPerson
|
return &dbPerson
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) GetPersonByDiscordID(discorId string) *DB_Person {
|
||||||
|
var discordEntry DB_DiscordPerson
|
||||||
|
s.Postgres.Model(&DB_DiscordPerson{}).Where("id = ?", discorId).Find(&discordEntry)
|
||||||
|
|
||||||
|
if discordEntry.ID == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.GetPerson(discordEntry.PersonID)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) GetAllPersons() []*DB_Person {
|
func (s *PostgresStorage) GetAllPersons() []*DB_Person {
|
||||||
var dbPersons []*DB_Person
|
var dbPersons []*DB_Person
|
||||||
|
|
||||||
s.Postgres.
|
s.Postgres.
|
||||||
|
Model(&DB_Person{}).
|
||||||
Preload("Profiles").
|
Preload("Profiles").
|
||||||
Preload("Profiles.Loadouts").
|
Preload("Profiles.Loadouts").
|
||||||
Preload("Profiles.Items.Variants").
|
Preload("Profiles.Items.Variants").
|
||||||
|
@ -103,6 +121,7 @@ func (s *PostgresStorage) GetAllPersons() []*DB_Person {
|
||||||
Preload("Profiles.Items").
|
Preload("Profiles.Items").
|
||||||
Preload("Profiles.Gifts").
|
Preload("Profiles.Gifts").
|
||||||
Preload("Profiles.Quests").
|
Preload("Profiles.Quests").
|
||||||
|
Preload("Discord").
|
||||||
Find(&dbPersons)
|
Find(&dbPersons)
|
||||||
|
|
||||||
return dbPersons
|
return dbPersons
|
||||||
|
@ -179,3 +198,19 @@ func (s *PostgresStorage) SaveLoadout(loadout *DB_Loadout) {
|
||||||
func (s *PostgresStorage) DeleteLoadout(loadoutId string) {
|
func (s *PostgresStorage) DeleteLoadout(loadoutId string) {
|
||||||
s.Postgres.Delete(&DB_Loadout{}, "id = ?", loadoutId)
|
s.Postgres.Delete(&DB_Loadout{}, "id = ?", loadoutId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveTemporaryCode(code *DB_TemporaryCode) {
|
||||||
|
s.Postgres.Save(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) DeleteTemporaryCode(codeId string) {
|
||||||
|
s.Postgres.Delete(&DB_TemporaryCode{}, "id = ?", codeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveDiscordPerson(discordPerson *DB_DiscordPerson) {
|
||||||
|
s.Postgres.Save(discordPerson)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) DeleteDiscordPerson(discordPersonId string) {
|
||||||
|
s.Postgres.Delete(&DB_DiscordPerson{}, "id = ?", discordPersonId)
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ type Storage interface {
|
||||||
|
|
||||||
GetPerson(personId string) *DB_Person
|
GetPerson(personId string) *DB_Person
|
||||||
GetPersonByDisplay(displayName string) *DB_Person
|
GetPersonByDisplay(displayName string) *DB_Person
|
||||||
|
GetPersonByDiscordID(discordId string) *DB_Person
|
||||||
GetAllPersons() []*DB_Person
|
GetAllPersons() []*DB_Person
|
||||||
SavePerson(person *DB_Person)
|
SavePerson(person *DB_Person)
|
||||||
|
|
||||||
|
@ -35,6 +36,12 @@ type Storage interface {
|
||||||
|
|
||||||
SaveLoadout(loadout *DB_Loadout)
|
SaveLoadout(loadout *DB_Loadout)
|
||||||
DeleteLoadout(loadoutId string)
|
DeleteLoadout(loadoutId string)
|
||||||
|
|
||||||
|
SaveTemporaryCode(code *DB_TemporaryCode)
|
||||||
|
DeleteTemporaryCode(codeId string)
|
||||||
|
|
||||||
|
SaveDiscordPerson(person *DB_DiscordPerson)
|
||||||
|
DeleteDiscordPerson(personId string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
|
@ -65,6 +72,15 @@ func (r *Repository) GetPersonByDisplayFromDB(displayName string) *DB_Person {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) GetPersonByDiscordIDFromDB(discordId string) *DB_Person {
|
||||||
|
storagePerson := r.Storage.GetPersonByDiscordID(discordId)
|
||||||
|
if storagePerson != nil {
|
||||||
|
return storagePerson
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) GetAllPersons() []*DB_Person {
|
func (r *Repository) GetAllPersons() []*DB_Person {
|
||||||
return r.Storage.GetAllPersons()
|
return r.Storage.GetAllPersons()
|
||||||
}
|
}
|
||||||
|
@ -136,3 +152,19 @@ func (r *Repository) SaveLoadout(loadout *DB_Loadout) {
|
||||||
func (r *Repository) DeleteLoadout(loadoutId string) {
|
func (r *Repository) DeleteLoadout(loadoutId string) {
|
||||||
r.Storage.DeleteLoadout(loadoutId)
|
r.Storage.DeleteLoadout(loadoutId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveTemporaryCode(code *DB_TemporaryCode) {
|
||||||
|
r.Storage.SaveTemporaryCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) DeleteTemporaryCode(codeId string) {
|
||||||
|
r.Storage.DeleteTemporaryCode(codeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveDiscordPerson(person *DB_DiscordPerson) {
|
||||||
|
r.Storage.SaveDiscordPerson(person)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Repository) DeleteDiscordPerson(personId string) {
|
||||||
|
r.Storage.DeleteDiscordPerson(personId)
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ type DB_Person struct {
|
||||||
DisplayName string
|
DisplayName string
|
||||||
AccessKey string
|
AccessKey string
|
||||||
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
||||||
|
Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"`
|
||||||
|
DiscordID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_Person) TableName() string {
|
func (DB_Person) TableName() string {
|
||||||
|
@ -134,3 +136,26 @@ type DB_Loot struct {
|
||||||
func (DB_Loot) TableName() string {
|
func (DB_Loot) TableName() string {
|
||||||
return "Loot"
|
return "Loot"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DB_TemporaryCode struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
Code string
|
||||||
|
ExpiresAt int64
|
||||||
|
PersonID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (DB_TemporaryCode) TableName() string {
|
||||||
|
return "Exchange"
|
||||||
|
}
|
||||||
|
|
||||||
|
type DB_DiscordPerson struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
PersonID string
|
||||||
|
Username string
|
||||||
|
AccessToken string
|
||||||
|
RefreshToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (DB_DiscordPerson) TableName() string {
|
||||||
|
return "Discord"
|
||||||
|
}
|
50
wiki/oauth.md
Normal file
50
wiki/oauth.md
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Configure Discord OAuth
|
||||||
|
|
||||||
|
## Getting your OAuth Credentials
|
||||||
|
|
||||||
|
![Alt text](oauth1.png)
|
||||||
|
|
||||||
|
![Alt text](oauth2.png)
|
||||||
|
|
||||||
|
Part of the file `config.ini` should look like this:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[discord]
|
||||||
|
; discord id of the bot
|
||||||
|
id="1234567890..."
|
||||||
|
; oauth2 client secret
|
||||||
|
secret="abcdefg..."
|
||||||
|
; discord bot token
|
||||||
|
token="OTK...."
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace the values with your own, save and rebuild to apply the changes.
|
||||||
|
|
||||||
|
## Setup the bot
|
||||||
|
|
||||||
|
Add the correct redirects to your discord application:
|
||||||
|
|
||||||
|
![Alt text](redirects.png)
|
||||||
|
|
||||||
|
This will be from the `config.ini` file:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[api]
|
||||||
|
port=":3000"
|
||||||
|
host="http://localhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure to add `/snow/discord` to the end of the redirect url.
|
||||||
|
|
||||||
|
## Inviting the bot
|
||||||
|
|
||||||
|
Generate an invite link for the bot with the following permissions:
|
||||||
|
|
||||||
|
![Alt text](scopes1.png)
|
||||||
|
![Alt text](scopes2.png)
|
||||||
|
|
||||||
|
The invite link should look like this:
|
||||||
|
|
||||||
|
```url
|
||||||
|
https://discord.com/api/oauth2/authorize?client_id=CLIENT_ID&permissions=34816&redirect_uri=CALLBACK_URL&scope=bot+applications.commands
|
||||||
|
```
|
BIN
wiki/oauth1.png
Normal file
BIN
wiki/oauth1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
wiki/oauth2.png
Normal file
BIN
wiki/oauth2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
wiki/redirects.png
Normal file
BIN
wiki/redirects.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
wiki/scopes1.png
Normal file
BIN
wiki/scopes1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
wiki/scopes2.png
Normal file
BIN
wiki/scopes2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
Loading…
Reference in New Issue
Block a user