firebase via REST (less dependencies)
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog/log"
|
||||
"time"
|
||||
)
|
||||
@@ -17,15 +18,17 @@ type AppContext struct {
|
||||
cancelled bool
|
||||
transaction *sql.Tx
|
||||
permissions PermissionSet
|
||||
ginContext *gin.Context
|
||||
}
|
||||
|
||||
func CreateAppContext(innerCtx context.Context, cancelFn context.CancelFunc) *AppContext {
|
||||
func CreateAppContext(g *gin.Context, innerCtx context.Context, cancelFn context.CancelFunc) *AppContext {
|
||||
return &AppContext{
|
||||
inner: innerCtx,
|
||||
cancelFunc: cancelFn,
|
||||
cancelled: false,
|
||||
transaction: nil,
|
||||
permissions: NewEmptyPermissions(),
|
||||
ginContext: g,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +51,24 @@ func (ac *AppContext) Value(key any) any {
|
||||
func (ac *AppContext) Cancel() {
|
||||
ac.cancelled = true
|
||||
if ac.transaction != nil {
|
||||
log.Error().Msg("Rollback transaction")
|
||||
log.Error().Str("uri", ac.RequestURI()).Msg("Rollback transaction (ctx-cancel)")
|
||||
err := ac.transaction.Rollback()
|
||||
if err != nil {
|
||||
panic("failed to rollback transaction: " + err.Error())
|
||||
log.Err(err).Stack().Msg("Failed to rollback transaction")
|
||||
}
|
||||
ac.transaction = nil
|
||||
}
|
||||
ac.cancelFunc()
|
||||
}
|
||||
|
||||
func (ac *AppContext) RequestURI() string {
|
||||
if ac.ginContext != nil && ac.ginContext.Request != nil {
|
||||
return ac.ginContext.Request.Method + " :: " + ac.ginContext.Request.RequestURI
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (ac *AppContext) FinishSuccess(res ginresp.HTTPResponse) ginresp.HTTPResponse {
|
||||
if ac.cancelled {
|
||||
panic("Cannot finish a cancelled request")
|
||||
@@ -65,7 +76,7 @@ func (ac *AppContext) FinishSuccess(res ginresp.HTTPResponse) ginresp.HTTPRespon
|
||||
if ac.transaction != nil {
|
||||
err := ac.transaction.Commit()
|
||||
if err != nil {
|
||||
return ginresp.InternAPIError(500, apierr.COMMIT_FAILED, "Failed to comit changes to DB", err)
|
||||
return ginresp.InternAPIError(ac.ginContext, 500, apierr.COMMIT_FAILED, "Failed to comit changes to DB", err)
|
||||
}
|
||||
ac.transaction = nil
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@ type Application struct {
|
||||
Config scn.Config
|
||||
Gin *gin.Engine
|
||||
Database *db.Database
|
||||
Firebase *firebase.App
|
||||
Firebase *firebase.FBConnector
|
||||
DefaultChannel string
|
||||
Jobs []Job
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func NewApp(db *db.Database) *Application {
|
||||
}
|
||||
}
|
||||
|
||||
func (app *Application) Init(cfg scn.Config, g *gin.Engine, fb *firebase.App, jobs []Job) {
|
||||
func (app *Application) Init(cfg scn.Config, g *gin.Engine, fb *firebase.FBConnector, jobs []Job) {
|
||||
app.Config = cfg
|
||||
app.Gin = g
|
||||
app.Firebase = fb
|
||||
@@ -122,37 +122,37 @@ func (app *Application) StartRequest(g *gin.Context, uri any, query any, body an
|
||||
|
||||
if uri != nil {
|
||||
if err := g.ShouldBindUri(uri); err != nil {
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(400, apierr.BINDFAIL_URI_PARAM, "Failed to read uri", err))
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(g, 400, apierr.BINDFAIL_URI_PARAM, "Failed to read uri", err))
|
||||
}
|
||||
}
|
||||
|
||||
if query != nil {
|
||||
if err := g.ShouldBindQuery(query); err != nil {
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(400, apierr.BINDFAIL_QUERY_PARAM, "Failed to read query", err))
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(g, 400, apierr.BINDFAIL_QUERY_PARAM, "Failed to read query", err))
|
||||
}
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
if body != nil && g.Request.Header.Get("Content-Type") == "application/javascript" {
|
||||
if err := g.ShouldBindJSON(body); err != nil {
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(400, apierr.BINDFAIL_BODY_PARAM, "Failed to read body", err))
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "Failed to read body", err))
|
||||
}
|
||||
}
|
||||
|
||||
if form != nil {
|
||||
if form != nil && g.Request.Header.Get("Content-Type") == "multipart/form-data" {
|
||||
if err := g.ShouldBindWith(form, binding.Form); err != nil {
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(400, apierr.BINDFAIL_BODY_PARAM, "Failed to read multipart-form", err))
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "Failed to read multipart-form", err))
|
||||
}
|
||||
}
|
||||
|
||||
ictx, cancel := context.WithTimeout(context.Background(), app.Config.RequestTimeout)
|
||||
actx := CreateAppContext(ictx, cancel)
|
||||
actx := CreateAppContext(g, ictx, cancel)
|
||||
|
||||
authheader := g.GetHeader("Authorization")
|
||||
|
||||
perm, err := app.getPermissions(actx, authheader)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(400, apierr.PERM_QUERY_FAIL, "Failed to determine permissions", err))
|
||||
return nil, langext.Ptr(ginresp.InternAPIError(g, 400, apierr.PERM_QUERY_FAIL, "Failed to determine permissions", err))
|
||||
}
|
||||
|
||||
actx.permissions = perm
|
||||
@@ -245,6 +245,7 @@ func (app *Application) DeliverMessage(ctx context.Context, client models.Client
|
||||
if client.FCMToken != nil {
|
||||
fcmDelivID, err := app.Firebase.SendNotification(ctx, client, msg)
|
||||
if err != nil {
|
||||
log.Warn().Int64("SCNMessageID", msg.SCNMessageID).Int64("ClientID", client.ClientID).Err(err).Msg("FCM Delivery failed")
|
||||
return nil, err
|
||||
}
|
||||
return langext.Ptr(fcmDelivID), nil
|
||||
|
@@ -28,8 +28,6 @@ func NewEmptyPermissions() PermissionSet {
|
||||
}
|
||||
}
|
||||
|
||||
var respoNotAuthorized = ginresp.InternAPIError(401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil)
|
||||
|
||||
func (ac *AppContext) CheckPermissionUserRead(userid int64) *ginresp.HTTPResponse {
|
||||
p := ac.permissions
|
||||
if p.UserID != nil && *p.UserID == userid && p.KeyType == PermKeyTypeUserRead {
|
||||
@@ -39,7 +37,7 @@ func (ac *AppContext) CheckPermissionUserRead(userid int64) *ginresp.HTTPRespons
|
||||
return nil
|
||||
}
|
||||
|
||||
return langext.Ptr(respoNotAuthorized)
|
||||
return langext.Ptr(ginresp.InternAPIError(ac.ginContext, 401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil))
|
||||
}
|
||||
|
||||
func (ac *AppContext) CheckPermissionRead() *ginresp.HTTPResponse {
|
||||
@@ -51,7 +49,7 @@ func (ac *AppContext) CheckPermissionRead() *ginresp.HTTPResponse {
|
||||
return nil
|
||||
}
|
||||
|
||||
return langext.Ptr(respoNotAuthorized)
|
||||
return langext.Ptr(ginresp.InternAPIError(ac.ginContext, 401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil))
|
||||
}
|
||||
|
||||
func (ac *AppContext) CheckPermissionUserAdmin(userid int64) *ginresp.HTTPResponse {
|
||||
@@ -60,13 +58,13 @@ func (ac *AppContext) CheckPermissionUserAdmin(userid int64) *ginresp.HTTPRespon
|
||||
return nil
|
||||
}
|
||||
|
||||
return langext.Ptr(respoNotAuthorized)
|
||||
return langext.Ptr(ginresp.InternAPIError(ac.ginContext, 401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil))
|
||||
}
|
||||
|
||||
func (ac *AppContext) CheckPermissionAny() *ginresp.HTTPResponse {
|
||||
p := ac.permissions
|
||||
if p.KeyType == PermKeyTypeNone {
|
||||
return langext.Ptr(respoNotAuthorized)
|
||||
return langext.Ptr(ginresp.InternAPIError(ac.ginContext, 401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -87,6 +87,7 @@ func (sc *SimpleContext) RollbackTransaction() {
|
||||
}
|
||||
err := sc.transaction.Rollback()
|
||||
if err != nil {
|
||||
log.Err(err).Stack().Msg("Failed to rollback transaction")
|
||||
panic(err)
|
||||
}
|
||||
sc.transaction = nil
|
||||
|
Reference in New Issue
Block a user