Use ID types

This commit is contained in:
2022-11-20 22:18:24 +01:00
parent ca58aa782d
commit 0cc6e27267
23 changed files with 334 additions and 256 deletions

View File

@@ -129,7 +129,7 @@ func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid} [GET]
func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
var u uri
@@ -177,7 +177,7 @@ func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid} [PATCH]
func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type body struct {
Username *string `json:"username"`
@@ -283,7 +283,7 @@ func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/clients [GET]
func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type response struct {
Clients []models.ClientJSON `json:"clients"`
@@ -327,8 +327,8 @@ func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/clients/{cid} [GET]
func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
ClientID int64 `uri:"cid"`
UserID models.UserID `uri:"uid"`
ClientID models.ClientID `uri:"cid"`
}
var u uri
@@ -371,7 +371,7 @@ func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/clients [POST]
func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type body struct {
FCMToken string `json:"fcm_token" binding:"required"`
@@ -426,8 +426,8 @@ func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/clients [POST]
func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
ClientID int64 `uri:"cid"`
UserID models.UserID `uri:"uid"`
ClientID models.ClientID `uri:"cid"`
}
var u uri
@@ -480,7 +480,7 @@ func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/channels [GET]
func (h APIHandler) ListChannels(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type query struct {
Selector *string `form:"selector"`
@@ -559,8 +559,8 @@ func (h APIHandler) ListChannels(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/channels/{cid} [GET]
func (h APIHandler) GetChannel(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
ChannelID int64 `uri:"cid"`
UserID models.UserID `uri:"uid"`
ChannelID models.ChannelID `uri:"cid"`
}
var u uri
@@ -605,8 +605,8 @@ func (h APIHandler) GetChannel(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/channels/{cid} [PATCH]
func (h APIHandler) UpdateChannel(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
ChannelID int64 `uri:"cid"`
UserID models.UserID `uri:"uid"`
ChannelID models.ChannelID `uri:"cid"`
}
type body struct {
RefreshSubscribeKey *bool `json:"subscribe_key"`
@@ -679,8 +679,8 @@ func (h APIHandler) UpdateChannel(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/channels/{cid}/messages [GET]
func (h APIHandler) ListChannelMessages(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
ChannelUserID int64 `uri:"uid"`
ChannelID int64 `uri:"cid"`
ChannelUserID models.UserID `uri:"uid"`
ChannelID models.ChannelID `uri:"cid"`
}
type query struct {
PageSize *int `form:"page_size"`
@@ -769,7 +769,7 @@ func (h APIHandler) ListChannelMessages(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/subscriptions [GET]
func (h APIHandler) ListUserSubscriptions(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type response struct {
Subscriptions []models.SubscriptionJSON `json:"subscriptions"`
@@ -813,8 +813,8 @@ func (h APIHandler) ListUserSubscriptions(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/channels/{cid}/subscriptions [GET]
func (h APIHandler) ListChannelSubscriptions(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
ChannelID int64 `uri:"cid"`
UserID models.UserID `uri:"uid"`
ChannelID models.ChannelID `uri:"cid"`
}
type response struct {
Subscriptions []models.SubscriptionJSON `json:"subscriptions"`
@@ -866,8 +866,8 @@ func (h APIHandler) ListChannelSubscriptions(g *gin.Context) ginresp.HTTPRespons
// @Router /api-v2/users/{uid}/subscriptions/{sid} [GET]
func (h APIHandler) GetSubscription(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
SubscriptionID int64 `uri:"sid"`
UserID models.UserID `uri:"uid"`
SubscriptionID models.SubscriptionID `uri:"sid"`
}
var u uri
@@ -913,8 +913,8 @@ func (h APIHandler) GetSubscription(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/subscriptions/{sid} [DELETE]
func (h APIHandler) CancelSubscription(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
SubscriptionID int64 `uri:"sid"`
UserID models.UserID `uri:"uid"`
SubscriptionID models.SubscriptionID `uri:"sid"`
}
var u uri
@@ -966,11 +966,11 @@ func (h APIHandler) CancelSubscription(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/subscriptions [POST]
func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
UserID models.UserID `uri:"uid"`
}
type body struct {
ChannelOwnerUserID int64 `form:"channel_owner_user_id" binding:"required"`
Channel string `form:"channel_name" binding:"required"`
ChannelOwnerUserID models.UserID `form:"channel_owner_user_id" binding:"required"`
Channel string `form:"channel_name" binding:"required"`
}
type query struct {
ChanSubscribeKey *string `form:"chan_subscribe_key"`
@@ -1026,8 +1026,8 @@ func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/users/{uid}/subscriptions/{sid} [PATCH]
func (h APIHandler) UpdateSubscription(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
UserID int64 `uri:"uid"`
SubscriptionID int64 `uri:"sid"`
UserID models.UserID `uri:"uid"`
SubscriptionID models.SubscriptionID `uri:"sid"`
}
type body struct {
Confirmed *bool `form:"confirmed"`
@@ -1166,7 +1166,7 @@ func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/messages/{mid} [PATCH]
func (h APIHandler) GetMessage(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
MessageID int64 `uri:"mid"`
MessageID models.SCNMessageID `uri:"mid"`
}
var u uri
@@ -1235,7 +1235,7 @@ func (h APIHandler) GetMessage(g *gin.Context) ginresp.HTTPResponse {
// @Router /api-v2/messages/{mid} [PATCH]
func (h APIHandler) DeleteMessage(g *gin.Context) ginresp.HTTPResponse {
type uri struct {
MessageID int64 `uri:"mid"`
MessageID models.SCNMessageID `uri:"mid"`
}
var u uri
@@ -1337,11 +1337,6 @@ func (h APIHandler) CreateMessage(g *gin.Context) ginresp.HTTPResponse {
return ginresp.SendAPIError(g, 400, apierr.USR_MSG_ID_TOO_LONG, -1, "MessageID too long (64 characters)", nil)
}
channelName := h.app.DefaultChannel
if b.Channel != nil {
channelName = h.app.NormalizeChannelName(*b.Channel)
}
user, err := h.database.GetUser(ctx, userID)
if err == sql.ErrNoRows {
return ginresp.SendAPIError(g, 400, apierr.USER_NOT_FOUND, -1, "User not found", nil)
@@ -1350,6 +1345,11 @@ func (h APIHandler) CreateMessage(g *gin.Context) ginresp.HTTPResponse {
return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query user", err)
}
channelName := user.DefaultChannel()
if b.Channel != nil {
channelName = h.app.NormalizeChannelName(*b.Channel)
}
if len(*b.Title) > user.MaxTitleLength() {
return ginresp.SendAPIError(g, 400, apierr.TITLE_TOO_LONG, 103, fmt.Sprintf("Title too long (max %d characters)", user.MaxTitleLength()), nil)
}

View File

@@ -122,7 +122,7 @@ func (h CompatHandler) Register(g *gin.Context) ginresp.HTTPResponse {
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
Success: true,
Message: "New user registered",
UserID: user.UserID,
UserID: user.UserID.IntID(),
UserKey: user.AdminKey,
QuotaUsed: user.QuotaUsedToday(),
QuotaMax: user.QuotaPerDay(),
@@ -180,7 +180,7 @@ func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(102, "Missing parameter [[user_key]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -202,7 +202,7 @@ func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse {
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
Success: true,
Message: "ok",
UserID: user.UserID,
UserID: user.UserID.IntID(),
UserKey: user.AdminKey,
QuotaUsed: user.QuotaUsedToday(),
QuotaMax: user.QuotaPerDay(),
@@ -263,7 +263,7 @@ func (h CompatHandler) Ack(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(103, "Missing parameter [[scn_msg_id]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -328,7 +328,7 @@ func (h CompatHandler) Requery(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(102, "Missing parameter [[user_key]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -399,7 +399,7 @@ func (h CompatHandler) Update(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(102, "Missing parameter [[user_key]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -451,7 +451,7 @@ func (h CompatHandler) Update(g *gin.Context) ginresp.HTTPResponse {
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
Success: true,
Message: "user updated",
UserID: user.UserID,
UserID: user.UserID.IntID(),
UserKey: user.AdminKey,
QuotaUsed: user.QuotaUsedToday(),
QuotaMax: user.QuotaPerDay(),
@@ -509,7 +509,7 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(103, "Missing parameter [[scn_msg_id]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -521,7 +521,7 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(204, "Authentification failed")
}
msg, err := h.database.GetMessage(ctx, *data.MessageID)
msg, err := h.database.GetMessage(ctx, models.SCNMessageID(*data.MessageID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(301, "Message not found")
}
@@ -539,7 +539,7 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse {
Priority: msg.Priority,
Timestamp: msg.Timestamp().Unix(),
UserMessageID: msg.UserMessageID,
SCNMessageID: msg.SCNMessageID,
SCNMessageID: msg.SCNMessageID.IntID(),
},
}))
}
@@ -603,7 +603,7 @@ func (h CompatHandler) Upgrade(g *gin.Context) ginresp.HTTPResponse {
return ginresp.CompatAPIError(104, "Missing parameter [[pro_token]]")
}
user, err := h.database.GetUser(ctx, *data.UserID)
user, err := h.database.GetUser(ctx, models.UserID(*data.UserID))
if err == sql.ErrNoRows {
return ginresp.CompatAPIError(201, "User not found")
}
@@ -648,7 +648,7 @@ func (h CompatHandler) Upgrade(g *gin.Context) ginresp.HTTPResponse {
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
Success: true,
Message: "user updated",
UserID: user.UserID,
UserID: user.UserID.IntID(),
QuotaUsed: user.QuotaUsedToday(),
QuotaMax: user.QuotaPerDay(),
IsPro: user.IsPro,

View File

@@ -5,6 +5,7 @@ import (
"blackforestbytes.com/simplecloudnotifier/common/ginresp"
"blackforestbytes.com/simplecloudnotifier/db"
"blackforestbytes.com/simplecloudnotifier/logic"
"blackforestbytes.com/simplecloudnotifier/models"
"database/sql"
"fmt"
"github.com/gin-gonic/gin"
@@ -49,22 +50,22 @@ func NewMessageHandler(app *logic.Application) MessageHandler {
// @Router /send.php [POST]
func (h MessageHandler) SendMessageCompat(g *gin.Context) ginresp.HTTPResponse {
type query struct {
UserID *int64 `form:"user_id"`
UserKey *string `form:"user_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
UserID *models.UserID `form:"user_id"`
UserKey *string `form:"user_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
}
type form struct {
UserID *int64 `form:"user_id"`
UserKey *string `form:"user_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
UserID *models.UserID `form:"user_id"`
UserKey *string `form:"user_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
}
var f form
@@ -77,7 +78,7 @@ func (h MessageHandler) SendMessageCompat(g *gin.Context) ginresp.HTTPResponse {
data := dataext.ObjectMerge(f, q)
return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, langext.Ptr(h.app.DefaultChannel), nil, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp)
return h.sendMessageInternal(g, ctx, data.UserID, data.UserKey, nil, nil, data.Title, data.Content, data.Priority, data.UserMessageID, data.SendTimestamp)
}
@@ -101,37 +102,37 @@ func (h MessageHandler) SendMessageCompat(g *gin.Context) ginresp.HTTPResponse {
// @Router /send [POST]
func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
type query struct {
UserID *int64 `form:"user_id"`
UserKey *string `form:"user_key"`
Channel *string `form:"channel"`
ChanKey *string `form:"chan_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
UserID *models.UserID `form:"user_id"`
UserKey *string `form:"user_key"`
Channel *string `form:"channel"`
ChanKey *string `form:"chan_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
}
type body struct {
UserID *int64 `json:"user_id"`
UserKey *string `json:"user_key"`
Channel *string `json:"channel"`
ChanKey *string `json:"chan_key"`
Title *string `json:"title"`
Content *string `json:"content"`
Priority *int `json:"priority"`
UserMessageID *string `json:"msg_id"`
SendTimestamp *float64 `json:"timestamp"`
UserID *models.UserID `json:"user_id"`
UserKey *string `json:"user_key"`
Channel *string `json:"channel"`
ChanKey *string `json:"chan_key"`
Title *string `json:"title"`
Content *string `json:"content"`
Priority *int `json:"priority"`
UserMessageID *string `json:"msg_id"`
SendTimestamp *float64 `json:"timestamp"`
}
type form struct {
UserID *int64 `form:"user_id"`
UserKey *string `form:"user_key"`
Channel *string `form:"channel"`
ChanKey *string `form:"chan_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
UserID *models.UserID `form:"user_id"`
UserKey *string `form:"user_key"`
Channel *string `form:"channel"`
ChanKey *string `form:"chan_key"`
Title *string `form:"title"`
Content *string `form:"content"`
Priority *int `form:"priority"`
UserMessageID *string `form:"msg_id"`
SendTimestamp *float64 `form:"timestamp"`
}
var b body
@@ -149,18 +150,18 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
}
func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContext, UserID *int64, UserKey *string, Channel *string, ChanKey *string, Title *string, Content *string, Priority *int, UserMessageID *string, SendTimestamp *float64) ginresp.HTTPResponse {
func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContext, UserID *models.UserID, UserKey *string, Channel *string, ChanKey *string, Title *string, Content *string, Priority *int, UserMessageID *string, SendTimestamp *float64) ginresp.HTTPResponse {
type response struct {
Success bool `json:"success"`
ErrorID apierr.APIError `json:"error"`
ErrorHighlight int `json:"errhighlight"`
Message string `json:"message"`
SuppressSend bool `json:"suppress_send"`
MessageCount int `json:"messagecount"`
Quota int `json:"quota"`
IsPro bool `json:"is_pro"`
QuotaMax int `json:"quota_max"`
SCNMessageID int64 `json:"scn_msg_id"`
Success bool `json:"success"`
ErrorID apierr.APIError `json:"error"`
ErrorHighlight int `json:"errhighlight"`
Message string `json:"message"`
SuppressSend bool `json:"suppress_send"`
MessageCount int `json:"messagecount"`
Quota int `json:"quota"`
IsPro bool `json:"is_pro"`
QuotaMax int `json:"quota_max"`
SCNMessageID models.SCNMessageID `json:"scn_msg_id"`
}
if Title != nil {
@@ -192,11 +193,6 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex
return ginresp.SendAPIError(g, 400, apierr.USR_MSG_ID_TOO_LONG, -1, "MessageID too long (64 characters)", nil)
}
channelName := h.app.DefaultChannel
if Channel != nil {
channelName = h.app.NormalizeChannelName(*Channel)
}
user, err := h.database.GetUser(ctx, *UserID)
if err == sql.ErrNoRows {
return ginresp.SendAPIError(g, 400, apierr.USER_NOT_FOUND, -1, "User not found", nil)
@@ -205,6 +201,11 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex
return ginresp.SendAPIError(g, 500, apierr.DATABASE_ERROR, -1, "Failed to query user", err)
}
channelName := user.DefaultChannel()
if Channel != nil {
channelName = h.app.NormalizeChannelName(*Channel)
}
if len(*Title) > user.MaxTitleLength() {
return ginresp.SendAPIError(g, 400, apierr.TITLE_TOO_LONG, 103, fmt.Sprintf("Title too long (max %d characters)", user.MaxTitleLength()), nil)
}