Skip to content

Commit

Permalink
Add API endpoint for setting config value
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaBernstein committed Apr 11, 2023
1 parent 749abf3 commit f51d319
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 8 deletions.
44 changes: 44 additions & 0 deletions api/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package config

import (
"fmt"
"log"
"net/http"
"strings"

Expand Down Expand Up @@ -51,3 +53,45 @@ func (r *Router) ReadConfig(c *gin.Context) {

c.JSON(http.StatusOK, settings)
}

type SettingsPost struct {
Setting string `json:"setting"`
Value interface{} `json:"value"`
}

func (r *Router) SetConfig(c *gin.Context) {
tgChatId := c.GetInt64("tgChatId")
var setting SettingsPost
err := c.ShouldBindJSON(&setting)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
if setting.Setting == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "could not read setting to update from body",
})
return
}
if setting.Setting == helpers.USERSET_ADM {
c.JSON(http.StatusUnauthorized, gin.H{
"error": "granting admin priviledges via API is not allowed",
})
return
}
if setting.Value == nil {
setting.Value = ""
}
log.Printf("Setting for user %d %s=%v", tgChatId, setting.Setting, setting.Value)
// TODO: Value assertions (int, string, bool)
err = r.bc.Repo.SetUserSetting(setting.Setting, fmt.Sprintf("%v", setting.Value), tgChatId)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.Status(http.StatusOK)
}
48 changes: 47 additions & 1 deletion api/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/LucaBernstein/beancount-bot-tg/api/config"
"github.com/LucaBernstein/beancount-bot-tg/api/helpers/apiTest"
"github.com/LucaBernstein/beancount-bot-tg/bot/botTest"
"github.com/LucaBernstein/beancount-bot-tg/db"
"github.com/LucaBernstein/beancount-bot-tg/helpers"
Expand Down Expand Up @@ -41,7 +42,7 @@ func AllSettingsTypes() ([]string, error) {
}

func TestFullConfigMap(t *testing.T) {
token, mockBc, msg := botTest.MockBcApiUser(t, 786)
token, mockBc, msg := apiTest.MockBcApiUser(t, 786)
err := PromoteAdmin(msg.Chat.ID)
botTest.HandleErr(t, err)

Expand Down Expand Up @@ -69,3 +70,48 @@ func TestFullConfigMap(t *testing.T) {
}

// TODO: For setting, check, that user cannot elevate to admin!
func TestSetConfig(t *testing.T) {
token, mockBc, _ := apiTest.MockBcApiUser(t, 427)

r := gin.Default()
g := r.Group("")
config.NewRouter(mockBc).Hook(g)

// Set tzOffset
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/", strings.NewReader(`{"setting":"user.tzOffset", "value":12}`))
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
r.ServeHTTP(w, req)

assert.Equal(t, 200, w.Result().StatusCode)

// Granting admin priviledges should not work
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/", strings.NewReader(`{"setting":"user.isAdmin", "value":true}`))
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
r.ServeHTTP(w, req)

assert.Equal(t, 401, w.Result().StatusCode)

// No settings field should fail
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/", strings.NewReader(`{"value":true}`))
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
r.ServeHTTP(w, req)

assert.Equal(t, 400, w.Result().StatusCode)

// Unsetting with null should work
w = httptest.NewRecorder()
req, _ = http.NewRequest("POST", "/", strings.NewReader(`{"setting":"user.currency", "value": null}`))
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
r.ServeHTTP(w, req)

assert.Equal(t, 200, w.Result().StatusCode)

// TODO: Enhance functionality coverage by looking at actual db states
}
1 change: 1 addition & 0 deletions api/config/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ func (r *Router) Hook(g *gin.RouterGroup) {
g.Use(helpers.AttachChatId(r.bc))

g.GET("/", r.ReadConfig)
g.POST("/", r.SetConfig)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package botTest
package apiTest

import (
"testing"

"github.com/LucaBernstein/beancount-bot-tg/bot"
"github.com/LucaBernstein/beancount-bot-tg/bot/botTest"
"github.com/LucaBernstein/beancount-bot-tg/db"
"github.com/LucaBernstein/beancount-bot-tg/db/crud"
"github.com/LucaBernstein/beancount-bot-tg/helpers"
Expand All @@ -18,13 +19,13 @@ func MockBcApiUser(t *testing.T, id int64) (token string, mockBc *bot.BotControl

msg := &telebot.Message{Chat: &telebot.Chat{ID: id}, Sender: &telebot.User{ID: id}}
err := mockBc.Repo.EnrichUserData(msg)
HandleErr(t, err)
botTest.HandleErr(t, err)
err = mockBc.Repo.SetUserSetting(helpers.USERSET_ENABLEAPI, "true", msg.Chat.ID)
HandleErr(t, err)
botTest.HandleErr(t, err)
nonce, err := mockBc.Repo.CreateApiVerification(msg.Chat.ID)
HandleErr(t, err)
botTest.HandleErr(t, err)
token, err = mockBc.Repo.VerifyApiToken(msg.Chat.ID, nonce)
HandleErr(t, err)
botTest.HandleErr(t, err)

return token, mockBc, msg
}
4 changes: 2 additions & 2 deletions api/helpers/chatId_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import (
"testing"

"github.com/LucaBernstein/beancount-bot-tg/api/helpers"
"github.com/LucaBernstein/beancount-bot-tg/bot/botTest"
"github.com/LucaBernstein/beancount-bot-tg/api/helpers/apiTest"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)

func TestChatIdEnrichment(t *testing.T) {
token, mockBc, m := botTest.MockBcApiUser(t, 442)
token, mockBc, m := apiTest.MockBcApiUser(t, 442)
handlerFn := helpers.AttachChatId(mockBc)

r := gin.Default()
Expand Down

0 comments on commit f51d319

Please sign in to comment.