mirror of
https://github.com/mgerb/go-discord-bot
synced 2026-01-09 16:42:48 +00:00
expanded permissions functionality - added packr for bundling static assets
This commit is contained in:
@@ -4,15 +4,9 @@ import jwt_decode from 'jwt-decode';
|
||||
import { StorageService } from '../../services';
|
||||
import './Navbar.scss';
|
||||
|
||||
let oauthUrl: string;
|
||||
const baseUrl = window.location.origin + '/oauth';
|
||||
|
||||
if (!process.env.NODE_ENV) {
|
||||
// dev
|
||||
oauthUrl = `https://discordapp.com/api/oauth2/authorize?client_id=410818759746650140&redirect_uri=https%3A%2F%2Flocalhost%2Foauth&response_type=code&scope=identify%20guilds`;
|
||||
} else {
|
||||
// prod
|
||||
oauthUrl = `https://discordapp.com/api/oauth2/authorize?client_id=271998875802402816&redirect_uri=https%3A%2F%2Fcashdiscord.com%2Foauth&response_type=code&scope=identify%20guilds%20email`;
|
||||
}
|
||||
const oauthUrl = `https://discordapp.com/api/oauth2/authorize?client_id=410818759746650140&redirect_uri=${baseUrl}&response_type=code&scope=identify%20guilds`;
|
||||
|
||||
interface Props {}
|
||||
|
||||
@@ -47,7 +41,7 @@ export class Navbar extends React.Component<Props, State> {
|
||||
render() {
|
||||
return (
|
||||
<div className="Navbar">
|
||||
<div className="Navbar__header">Cash</div>
|
||||
<div className="Navbar__header">Sound Bot</div>
|
||||
<NavLink exact to="/" className="Navbar__item" activeClassName="Navbar__item--active">
|
||||
Home
|
||||
</NavLink>
|
||||
|
||||
@@ -34,6 +34,7 @@ export class Stats extends Component<any, IState> {
|
||||
return { username: k, count: v };
|
||||
})
|
||||
.orderBy(v => v.count, 'desc')
|
||||
.slice(0, 10)
|
||||
.value();
|
||||
|
||||
this.setState({ data });
|
||||
@@ -61,8 +62,8 @@ export class Stats extends Component<any, IState> {
|
||||
return (
|
||||
<div className="content">
|
||||
<div className="card" style={{ maxWidth: '1000px' }}>
|
||||
<div className="card__header">Shitposts</div>
|
||||
<HorizontalBar data={data} height={500} />
|
||||
<div className="card__header">Posts containing links</div>
|
||||
<HorizontalBar data={data} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"bot_prefix": "#",
|
||||
|
||||
"admin_emails": ["mail@example.com"],
|
||||
"mod_emails": ["mail@example.com"],
|
||||
|
||||
"jwt_key": "",
|
||||
"server_addr": "0.0.0.0:80",
|
||||
|
||||
4
makefile
4
makefile
@@ -5,7 +5,7 @@ install:
|
||||
go get && cd client && npm install
|
||||
|
||||
build-server:
|
||||
go build -o bot ./main.go
|
||||
packr build -o bot ./main.go && packr install
|
||||
|
||||
build-client:
|
||||
cd client && npm run build
|
||||
@@ -13,4 +13,4 @@ build-client:
|
||||
clean:
|
||||
rm -rf bot ./dist
|
||||
|
||||
all: install build-server build-client
|
||||
all: install build-client build-server
|
||||
|
||||
93
readme.md
93
readme.md
@@ -1,51 +1,88 @@
|
||||
# Discord Sound Bot
|
||||
|
||||
This is a soundboard bot for discord. The back end is in GoLang and the front end uses React.
|
||||
A soundboard bot for discord with a Go back end and React front end.
|
||||
|
||||
<img src="http://i.imgur.com/jtAyJZ1.png"/>
|
||||

|
||||
|
||||
## How to use
|
||||
|
||||
NOTE: Currently the binaries in the release package only run on linux. Check them out [here](https://github.com/mgerb/go-discord-bot/releases)
|
||||
* [Download latest release here](https://github.com/mgerb/go-discord-bot/releases)
|
||||
* Install [youtube-dl](https://github.com/rg3/youtube-dl/blob/master/README.md#installation)
|
||||
* Install [ffmpeg](https://www.ffmpeg.org/download.html)
|
||||
* edit your config.json file
|
||||
* run the executable
|
||||
|
||||
- download bot.zip and extract everything
|
||||
- rename config.template.json to config.json
|
||||
- add your bot token and preferred upload password (leave as is for no password)
|
||||
- run the bot with `./bot` (you may need to use sudo if you leave it on port 80)
|
||||
### Commands
|
||||
|
||||
## Flags
|
||||
* `clip` - clips the past minute of audio
|
||||
* `summon` - summons the bot to your current channel
|
||||
* `dismiss` - dismisses the bot from the server
|
||||
* `<audio clip>` - play a named audio clip
|
||||
|
||||
> -p, run in production mode
|
||||
### Uploading files
|
||||
|
||||
> -tls, run with auto tls
|
||||
Discord oauth is used to authenticate users in order to upload files.
|
||||
To get oauth working you must set up your bot client secret/id in the config.
|
||||
You must also set up the redirect URI. This is needed so discord can redirect
|
||||
back to your site after authentication. Discord doesn't like insecure redirects
|
||||
so you will have to use a proxy for this. I prefer using [caddy](https://github.com/mholt/caddy)
|
||||
with the following config.
|
||||
|
||||
## Setting up Youtube downloader
|
||||
```
|
||||
https://localhost {
|
||||
tls self_signed
|
||||
proxy / http://localhost:8080 {
|
||||
transparent
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Install [youtube-dl](https://github.com/rg3/youtube-dl/blob/master/README.md#installation)
|
||||
For public hosting you will want to use something like this.
|
||||
|
||||
### NOTE
|
||||
```
|
||||
https://<your domain name> {
|
||||
tls <your email>
|
||||
proxy / http://localhost:8080 {
|
||||
transparent
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you get a permissions error with ffmpeg on mac or linux:
|
||||
`sudo chmod +x dist/ffmpeg_linux`
|
||||
### Clipping audio
|
||||
|
||||
Sounds are stored in the `sounds` directory. You may copy files directly to this folder rather than uploading through the site.
|
||||
If the bot is in a channel it listens to all audio. Use the `clip` command
|
||||
to record the past minute of conversation. Access all clips in the "Clips"
|
||||
section of the site.
|
||||
|
||||
### Stats
|
||||
|
||||
If logging is enabled the bot will log all messages and store in a database file. Currently the bot keeps track of
|
||||
all messages that contain links in them. I added this because it's something we use in my discord.
|
||||
Check it out in the "Stats" page on the site.
|
||||
|
||||
## Building from Source
|
||||
|
||||
### Dependencies
|
||||
- Go
|
||||
- node/npm
|
||||
- make
|
||||
|
||||
* Go
|
||||
* node/npm
|
||||
* make
|
||||
|
||||
### Compiling
|
||||
- Make sure dependencies are installed
|
||||
- `make all`
|
||||
- Rename the `config.template.json` to `config.json`
|
||||
- add configurations to `config.json`
|
||||
- run the executable
|
||||
- open a browser `localhost:<port>`
|
||||
- upload files
|
||||
- success!
|
||||
|
||||
* Make sure dependencies are installed
|
||||
* Rename the `config.template.json` to `config.json`
|
||||
* add configurations to `config.json`
|
||||
* `cd client && npm run dev`
|
||||
* `go run main.go`
|
||||
* open a browser `localhost:<config_port>`
|
||||
|
||||
[Packr](https://github.com/gobuffalo/packr) is used to bundle the static web assets into the binary.
|
||||
Use these commands to compile the project. The client must be built first.
|
||||
|
||||
* `packr build`
|
||||
* `packr install`
|
||||
|
||||
### Windows
|
||||
I've only compiled and run this on linux so far, but I've recently added cross platform support.
|
||||
|
||||
I only run this on linux. I'm not sure if it will work on windows, but it should without too much work.
|
||||
|
||||
@@ -33,22 +33,23 @@ const (
|
||||
)
|
||||
|
||||
// store our connection objects in a map tied to a guild id
|
||||
var activeConnections = make(map[string]*audioConnection)
|
||||
var activeConnections = make(map[string]*AudioConnection)
|
||||
|
||||
type audioConnection struct {
|
||||
guild *discordgo.Guild
|
||||
session *discordgo.Session
|
||||
voiceConnection *discordgo.VoiceConnection
|
||||
currentChannel *discordgo.Channel
|
||||
sounds map[string]*audioClip
|
||||
soundQueue chan string
|
||||
voiceClipQueue chan *discordgo.Packet
|
||||
soundPlayingLock bool
|
||||
audioListenerLock bool
|
||||
mutex *sync.Mutex // mutex for single audio connection
|
||||
// AudioConnection -
|
||||
type AudioConnection struct {
|
||||
Guild *discordgo.Guild `json:"guild"`
|
||||
Session *discordgo.Session `json:"-"`
|
||||
VoiceConnection *discordgo.VoiceConnection `json:"-"`
|
||||
CurrentChannel *discordgo.Channel `json:"current_channel"`
|
||||
Sounds map[string]*AudioClip `json:"-"`
|
||||
SoundQueue chan string `json:"-"`
|
||||
VoiceClipQueue chan *discordgo.Packet `json:"-"`
|
||||
SoundPlayingLock bool `json:"-"`
|
||||
AudioListenerLock bool `json:"-"`
|
||||
Mutex *sync.Mutex `json:"-"` // mutex for single audio connection
|
||||
}
|
||||
|
||||
type audioClip struct {
|
||||
type AudioClip struct {
|
||||
Name string
|
||||
Extension string
|
||||
Content [][]byte
|
||||
@@ -76,13 +77,13 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
}
|
||||
|
||||
// create new connection instance
|
||||
newInstance := &audioConnection{
|
||||
guild: newGuild,
|
||||
session: s,
|
||||
sounds: make(map[string]*audioClip, 0),
|
||||
soundQueue: make(chan string, maxSoundQueue),
|
||||
mutex: &sync.Mutex{},
|
||||
audioListenerLock: false,
|
||||
newInstance := &AudioConnection{
|
||||
Guild: newGuild,
|
||||
Session: s,
|
||||
Sounds: make(map[string]*AudioClip, 0),
|
||||
SoundQueue: make(chan string, maxSoundQueue),
|
||||
Mutex: &sync.Mutex{},
|
||||
AudioListenerLock: false,
|
||||
}
|
||||
|
||||
activeConnections[c.GuildID] = newInstance
|
||||
@@ -95,7 +96,7 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
go activeConnections[c.GuildID].handleMessage(m)
|
||||
}
|
||||
|
||||
func (conn *audioConnection) handleMessage(m *discordgo.MessageCreate) {
|
||||
func (conn *AudioConnection) handleMessage(m *discordgo.MessageCreate) {
|
||||
|
||||
// check if valid command
|
||||
if strings.HasPrefix(m.Content, config.Config.BotPrefix) {
|
||||
@@ -120,22 +121,22 @@ func (conn *audioConnection) handleMessage(m *discordgo.MessageCreate) {
|
||||
}
|
||||
|
||||
// dismiss bot from currnet channel if it's in one
|
||||
func (conn *audioConnection) dismiss() {
|
||||
if conn.voiceConnection != nil && !conn.soundPlayingLock && len(conn.soundQueue) == 0 {
|
||||
conn.voiceConnection.Disconnect()
|
||||
func (conn *AudioConnection) dismiss() {
|
||||
if conn.VoiceConnection != nil && !conn.SoundPlayingLock && len(conn.SoundQueue) == 0 {
|
||||
conn.VoiceConnection.Disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
// summon bot to channel that user is currently in
|
||||
func (conn *audioConnection) summon(m *discordgo.MessageCreate) {
|
||||
func (conn *AudioConnection) summon(m *discordgo.MessageCreate) {
|
||||
|
||||
// Join the channel the user issued the command from if not in it
|
||||
if conn.voiceConnection == nil || conn.voiceConnection.ChannelID != m.ChannelID {
|
||||
if conn.VoiceConnection == nil || conn.VoiceConnection.ChannelID != m.ChannelID {
|
||||
|
||||
var err error
|
||||
|
||||
// Find the channel that the message came from.
|
||||
c, err := conn.session.State.Channel(m.ChannelID)
|
||||
c, err := conn.Session.State.Channel(m.ChannelID)
|
||||
if err != nil {
|
||||
// Could not find channel.
|
||||
log.Error("User channel not found.")
|
||||
@@ -143,7 +144,7 @@ func (conn *audioConnection) summon(m *discordgo.MessageCreate) {
|
||||
}
|
||||
|
||||
// Find the guild for that channel.
|
||||
g, err := conn.session.State.Guild(c.GuildID)
|
||||
g, err := conn.Session.State.Guild(c.GuildID)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return
|
||||
@@ -153,19 +154,19 @@ func (conn *audioConnection) summon(m *discordgo.MessageCreate) {
|
||||
for _, vs := range g.VoiceStates {
|
||||
if vs.UserID == m.Author.ID {
|
||||
|
||||
conn.voiceConnection, err = conn.session.ChannelVoiceJoin(g.ID, vs.ChannelID, false, false)
|
||||
conn.VoiceConnection, err = conn.Session.ChannelVoiceJoin(g.ID, vs.ChannelID, false, false)
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// set the current channel
|
||||
conn.currentChannel = c
|
||||
conn.CurrentChannel = c
|
||||
|
||||
// start listening to audio if not locked
|
||||
if !conn.audioListenerLock {
|
||||
if !conn.AudioListenerLock {
|
||||
go conn.startAudioListener()
|
||||
conn.audioListenerLock = true
|
||||
conn.AudioListenerLock = true
|
||||
}
|
||||
|
||||
return
|
||||
@@ -176,10 +177,10 @@ func (conn *audioConnection) summon(m *discordgo.MessageCreate) {
|
||||
}
|
||||
|
||||
// play audio in channel that user is in
|
||||
func (conn *audioConnection) playAudio(soundName string, m *discordgo.MessageCreate) {
|
||||
func (conn *AudioConnection) playAudio(soundName string, m *discordgo.MessageCreate) {
|
||||
|
||||
// check if sound exists in memory
|
||||
if _, ok := conn.sounds[soundName]; !ok {
|
||||
if _, ok := conn.Sounds[soundName]; !ok {
|
||||
// try to load the sound if not found in memory
|
||||
err := conn.loadFile(soundName)
|
||||
|
||||
@@ -194,7 +195,7 @@ func (conn *audioConnection) playAudio(soundName string, m *discordgo.MessageCre
|
||||
|
||||
// add sound to queue if queue isn't full
|
||||
select {
|
||||
case conn.soundQueue <- soundName:
|
||||
case conn.SoundQueue <- soundName:
|
||||
|
||||
default:
|
||||
return
|
||||
@@ -203,7 +204,7 @@ func (conn *audioConnection) playAudio(soundName string, m *discordgo.MessageCre
|
||||
}
|
||||
|
||||
// load audio file into memory
|
||||
func (conn *audioConnection) loadFile(fileName string) error {
|
||||
func (conn *AudioConnection) loadFile(fileName string) error {
|
||||
|
||||
// scan directory for file
|
||||
files, _ := ioutil.ReadDir(config.Config.SoundsPath)
|
||||
@@ -250,7 +251,7 @@ func (conn *audioConnection) loadFile(fileName string) error {
|
||||
return errors.New("NewEncoder error.")
|
||||
}
|
||||
|
||||
conn.sounds[fileName] = &audioClip{
|
||||
conn.Sounds[fileName] = &AudioClip{
|
||||
Content: make([][]byte, 0),
|
||||
Name: fileName,
|
||||
Extension: fextension,
|
||||
@@ -274,17 +275,17 @@ func (conn *audioConnection) loadFile(fileName string) error {
|
||||
}
|
||||
|
||||
// append sound bytes to the content for this audio file
|
||||
conn.sounds[fileName].Content = append(conn.sounds[fileName].Content, opus)
|
||||
conn.Sounds[fileName].Content = append(conn.Sounds[fileName].Content, opus)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (conn *audioConnection) clipAudio(m *discordgo.MessageCreate) {
|
||||
if len(conn.voiceClipQueue) < 10 {
|
||||
conn.session.ChannelMessageSend(m.ChannelID, "Clip failed.")
|
||||
func (conn *AudioConnection) clipAudio(m *discordgo.MessageCreate) {
|
||||
if len(conn.VoiceClipQueue) < 10 {
|
||||
conn.Session.ChannelMessageSend(m.ChannelID, "Clip failed.")
|
||||
} else {
|
||||
writePacketsToFile(m.Author.Username, conn.voiceClipQueue)
|
||||
conn.session.ChannelMessageSend(m.ChannelID, "Sound clipped!")
|
||||
writePacketsToFile(m.Author.Username, conn.VoiceClipQueue)
|
||||
conn.Session.ChannelMessageSend(m.ChannelID, "Sound clipped!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,10 +330,10 @@ loop:
|
||||
}
|
||||
|
||||
// start listening to the voice channel
|
||||
func (conn *audioConnection) startAudioListener() {
|
||||
func (conn *AudioConnection) startAudioListener() {
|
||||
|
||||
if conn.voiceClipQueue == nil {
|
||||
conn.voiceClipQueue = make(chan *discordgo.Packet, voiceClipQueuePacketSize)
|
||||
if conn.VoiceClipQueue == nil {
|
||||
conn.VoiceClipQueue = make(chan *discordgo.Packet, voiceClipQueuePacketSize)
|
||||
}
|
||||
|
||||
speakers := make(map[uint32]*gopus.Decoder)
|
||||
@@ -343,7 +344,7 @@ loop:
|
||||
|
||||
select {
|
||||
// grab incomming audio
|
||||
case opusChannel, ok := <-conn.voiceConnection.OpusRecv:
|
||||
case opusChannel, ok := <-conn.VoiceConnection.OpusRecv:
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@@ -365,16 +366,16 @@ loop:
|
||||
}
|
||||
|
||||
// if channel is full trim off from beginning
|
||||
if len(conn.voiceClipQueue) == cap(conn.voiceClipQueue) {
|
||||
<-conn.voiceClipQueue
|
||||
if len(conn.VoiceClipQueue) == cap(conn.VoiceClipQueue) {
|
||||
<-conn.VoiceClipQueue
|
||||
}
|
||||
|
||||
// add current packet to channel queue
|
||||
conn.voiceClipQueue <- opusChannel
|
||||
conn.VoiceClipQueue <- opusChannel
|
||||
|
||||
// check if voice connection fails then break out of audio listener
|
||||
default:
|
||||
if !conn.voiceConnection.Ready {
|
||||
if !conn.VoiceConnection.Ready {
|
||||
break loop
|
||||
}
|
||||
|
||||
@@ -385,31 +386,31 @@ loop:
|
||||
}
|
||||
|
||||
// remove lock upon exit
|
||||
conn.audioListenerLock = false
|
||||
conn.AudioListenerLock = false
|
||||
}
|
||||
|
||||
// playSounds - plays the current buffer to the provided channel.
|
||||
func (conn *audioConnection) playSounds() (err error) {
|
||||
func (conn *AudioConnection) playSounds() (err error) {
|
||||
|
||||
for {
|
||||
newSoundName := <-conn.soundQueue
|
||||
newSoundName := <-conn.SoundQueue
|
||||
|
||||
conn.toggleSoundPlayingLock(true)
|
||||
|
||||
if !conn.voiceConnection.Ready {
|
||||
if !conn.VoiceConnection.Ready {
|
||||
continue
|
||||
}
|
||||
|
||||
// Start speaking.
|
||||
_ = conn.voiceConnection.Speaking(true)
|
||||
_ = conn.VoiceConnection.Speaking(true)
|
||||
|
||||
// Send the buffer data.
|
||||
for _, buff := range conn.sounds[newSoundName].Content {
|
||||
conn.voiceConnection.OpusSend <- buff
|
||||
for _, buff := range conn.Sounds[newSoundName].Content {
|
||||
conn.VoiceConnection.OpusSend <- buff
|
||||
}
|
||||
|
||||
// Stop speaking
|
||||
_ = conn.voiceConnection.Speaking(false)
|
||||
_ = conn.VoiceConnection.Speaking(false)
|
||||
|
||||
// Sleep for a specificed amount of time before ending.
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
@@ -419,10 +420,10 @@ func (conn *audioConnection) playSounds() (err error) {
|
||||
|
||||
}
|
||||
|
||||
func (conn *audioConnection) toggleSoundPlayingLock(playing bool) {
|
||||
conn.mutex.Lock()
|
||||
conn.soundPlayingLock = playing
|
||||
conn.mutex.Unlock()
|
||||
func (conn *AudioConnection) toggleSoundPlayingLock(playing bool) {
|
||||
conn.Mutex.Lock()
|
||||
conn.SoundPlayingLock = playing
|
||||
conn.Mutex.Unlock()
|
||||
}
|
||||
|
||||
func checkErr(err error) {
|
||||
|
||||
@@ -28,6 +28,7 @@ type configFile struct {
|
||||
ClipsPath string `json:"clips_path"`
|
||||
|
||||
AdminEmails []string `json:"admin_emails"`
|
||||
ModEmails []string `json:"mod_emails"`
|
||||
ServerAddr string `json:"server_addr"`
|
||||
JWTKey string `json:"jwt_key"`
|
||||
|
||||
|
||||
@@ -11,27 +11,34 @@ import (
|
||||
"gopkg.in/dgrijalva/jwt-go.v3"
|
||||
)
|
||||
|
||||
// permission levels
|
||||
const (
|
||||
PermAdmin = 3
|
||||
PermMod = 2
|
||||
PermUser = 1
|
||||
)
|
||||
|
||||
// CustomClaims -
|
||||
type CustomClaims struct {
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Discriminator string `json:"discriminator"`
|
||||
Email string `json:"email"`
|
||||
Permissions string `json:"permissions"`
|
||||
Permissions int `json:"permissions"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
// GetJWT - get json web token
|
||||
func GetJWT(user discord.User) (string, error) {
|
||||
|
||||
permissions := "user"
|
||||
permissions := PermUser
|
||||
|
||||
// check if email is in config admin list
|
||||
for _, email := range config.Config.AdminEmails {
|
||||
if user.Email == email {
|
||||
permissions = "admin"
|
||||
break
|
||||
}
|
||||
if checkEmailPermissions(user.Email, config.Config.ModEmails) {
|
||||
permissions = PermMod
|
||||
}
|
||||
|
||||
if checkEmailPermissions(user.Email, config.Config.AdminEmails) {
|
||||
permissions = PermAdmin
|
||||
}
|
||||
|
||||
claims := CustomClaims{
|
||||
@@ -50,6 +57,31 @@ func GetJWT(user discord.User) (string, error) {
|
||||
return token.SignedString([]byte(config.Config.JWTKey))
|
||||
}
|
||||
|
||||
func checkEmailPermissions(email string, emails []string) bool {
|
||||
for _, e := range emails {
|
||||
if email == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AuthPermissions - secure end points based on auth levels
|
||||
func AuthPermissions(p int) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
cl, _ := c.Get("claims")
|
||||
|
||||
if claims, ok := cl.(*CustomClaims); ok {
|
||||
if p <= claims.Permissions {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
unauthorizedResponse(c, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// AuthorizedJWT - jwt middleware
|
||||
func AuthorizedJWT() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
@@ -58,8 +90,7 @@ func AuthorizedJWT() gin.HandlerFunc {
|
||||
tokenString := strings.Split(c.GetHeader("Authorization"), " ")
|
||||
|
||||
if len(tokenString) != 2 {
|
||||
c.JSON(401, "Unauthorized")
|
||||
c.Abort()
|
||||
unauthorizedResponse(c, nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -69,9 +100,7 @@ func AuthorizedJWT() gin.HandlerFunc {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
c.JSON(401, "Unauthorized")
|
||||
c.Abort()
|
||||
unauthorizedResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -79,12 +108,18 @@ func AuthorizedJWT() gin.HandlerFunc {
|
||||
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
|
||||
c.Set("claims", claims)
|
||||
} else {
|
||||
log.Error(err)
|
||||
c.JSON(401, "Unauthorized")
|
||||
c.Abort()
|
||||
unauthorizedResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func unauthorizedResponse(c *gin.Context, err error) {
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
c.JSON(401, "unauthorized")
|
||||
c.Abort()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package webserver
|
||||
|
||||
import (
|
||||
"github.com/gobuffalo/packr"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mgerb/go-discord-bot/server/config"
|
||||
"github.com/mgerb/go-discord-bot/server/webserver/handlers"
|
||||
@@ -10,13 +12,15 @@ import (
|
||||
func getRouter() *gin.Engine {
|
||||
router := gin.Default()
|
||||
|
||||
router.Static("/static", "./dist/static")
|
||||
box := packr.NewBox("../../dist/static")
|
||||
|
||||
router.StaticFS("/static", box)
|
||||
router.Static("/public/sounds", config.Config.SoundsPath)
|
||||
router.Static("/public/youtube", "./youtube")
|
||||
router.Static("/public/clips", config.Config.ClipsPath)
|
||||
|
||||
router.NoRoute(func(c *gin.Context) {
|
||||
c.File("./dist/static/index.html")
|
||||
c.Data(200, "text/html", box.Bytes("index.html"))
|
||||
})
|
||||
|
||||
api := router.Group("/api")
|
||||
|
||||
Reference in New Issue
Block a user