2023-01-17 20:08:00 +00:00
package couchbase
import (
"context"
"encoding/json"
"fmt"
"log"
"strings"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
)
// AddWebhook to add webhook
2023-07-31 11:12:11 +00:00
func ( p * provider ) AddWebhook ( ctx context . Context , webhook * models . Webhook ) ( * model . Webhook , error ) {
2023-01-17 20:08:00 +00:00
if webhook . ID == "" {
webhook . ID = uuid . New ( ) . String ( )
}
webhook . Key = webhook . ID
webhook . CreatedAt = time . Now ( ) . Unix ( )
webhook . UpdatedAt = time . Now ( ) . Unix ( )
2023-03-26 01:50:45 +00:00
// Add timestamp to make event name unique for legacy version
webhook . EventName = fmt . Sprintf ( "%s-%d" , webhook . EventName , time . Now ( ) . Unix ( ) )
2023-01-17 20:08:00 +00:00
insertOpt := gocb . InsertOptions {
Context : ctx ,
}
_ , err := p . db . Collection ( models . Collections . Webhook ) . Insert ( webhook . ID , webhook , & insertOpt )
if err != nil {
2024-04-02 09:55:11 +00:00
return nil , err
2023-01-17 20:08:00 +00:00
}
return webhook . AsAPIWebhook ( ) , nil
}
// UpdateWebhook to update webhook
2023-07-31 11:12:11 +00:00
func ( p * provider ) UpdateWebhook ( ctx context . Context , webhook * models . Webhook ) ( * model . Webhook , error ) {
2023-01-17 20:08:00 +00:00
webhook . UpdatedAt = time . Now ( ) . Unix ( )
2023-03-26 01:50:45 +00:00
// Event is changed
if ! strings . Contains ( webhook . EventName , "-" ) {
webhook . EventName = fmt . Sprintf ( "%s-%d" , webhook . EventName , time . Now ( ) . Unix ( ) )
}
2023-01-17 20:08:00 +00:00
bytes , err := json . Marshal ( webhook )
if err != nil {
return nil , err
}
// use decoder instead of json.Unmarshall, because it converts int64 -> float64 after unmarshalling
decoder := json . NewDecoder ( strings . NewReader ( string ( bytes ) ) )
decoder . UseNumber ( )
webhookMap := map [ string ] interface { } { }
err = decoder . Decode ( & webhookMap )
if err != nil {
return nil , err
}
updateFields , params := GetSetFields ( webhookMap )
query := fmt . Sprintf ( ` UPDATE %s.%s SET %s WHERE _id='%s' ` , p . scopeName , models . Collections . Webhook , updateFields , webhook . ID )
_ , err = p . db . Query ( query , & gocb . QueryOptions {
Context : ctx ,
ScanConsistency : gocb . QueryScanConsistencyRequestPlus ,
NamedParameters : params ,
} )
if err != nil {
return nil , err
}
return webhook . AsAPIWebhook ( ) , nil
}
// ListWebhooks to list webhook
2023-07-31 11:12:11 +00:00
func ( p * provider ) ListWebhook ( ctx context . Context , pagination * model . Pagination ) ( * model . Webhooks , error ) {
2023-01-17 20:08:00 +00:00
webhooks := [ ] * model . Webhook { }
paginationClone := pagination
params := make ( map [ string ] interface { } , 1 )
params [ "offset" ] = paginationClone . Offset
params [ "limit" ] = paginationClone . Limit
2023-02-02 07:36:18 +00:00
total , err := p . GetTotalDocs ( ctx , models . Collections . Webhook )
if err != nil {
return nil , err
}
paginationClone . Total = total
2023-03-26 02:18:06 +00:00
query := fmt . Sprintf ( "SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit" , p . scopeName , models . Collections . Webhook )
2023-01-17 20:08:00 +00:00
queryResult , err := p . db . Query ( query , & gocb . QueryOptions {
Context : ctx ,
ScanConsistency : gocb . QueryScanConsistencyRequestPlus ,
NamedParameters : params ,
} )
if err != nil {
return nil , err
}
for queryResult . Next ( ) {
2023-08-01 10:39:17 +00:00
var webhook models . Webhook
2023-01-17 20:08:00 +00:00
err := queryResult . Row ( & webhook )
if err != nil {
log . Fatal ( err )
}
webhooks = append ( webhooks , webhook . AsAPIWebhook ( ) )
}
2023-03-29 01:36:33 +00:00
if err := queryResult . Err ( ) ; err != nil {
return nil , err
}
2023-01-17 20:08:00 +00:00
return & model . Webhooks {
2023-07-31 11:12:11 +00:00
Pagination : paginationClone ,
2023-01-17 20:08:00 +00:00
Webhooks : webhooks ,
} , nil
}
// GetWebhookByID to get webhook by id
func ( p * provider ) GetWebhookByID ( ctx context . Context , webhookID string ) ( * model . Webhook , error ) {
2023-07-31 11:12:11 +00:00
var webhook * models . Webhook
2023-01-17 20:08:00 +00:00
params := make ( map [ string ] interface { } , 1 )
params [ "_id" ] = webhookID
2023-03-26 02:18:06 +00:00
query := fmt . Sprintf ( ` SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1 ` , p . scopeName , models . Collections . Webhook )
2023-01-17 20:08:00 +00:00
q , err := p . db . Query ( query , & gocb . QueryOptions {
Context : ctx ,
ScanConsistency : gocb . QueryScanConsistencyRequestPlus ,
NamedParameters : params ,
} )
if err != nil {
return nil , err
}
err = q . One ( & webhook )
if err != nil {
return nil , err
}
return webhook . AsAPIWebhook ( ) , nil
}
// GetWebhookByEventName to get webhook by event_name
2023-03-26 01:50:45 +00:00
func ( p * provider ) GetWebhookByEventName ( ctx context . Context , eventName string ) ( [ ] * model . Webhook , error ) {
2023-01-17 20:08:00 +00:00
params := make ( map [ string ] interface { } , 1 )
2023-03-29 01:36:33 +00:00
// params["event_name"] = eventName + "%"
query := fmt . Sprintf ( ` SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name LIKE '%s' ` , p . scopeName , models . Collections . Webhook , eventName + "%" )
2023-03-26 01:50:45 +00:00
queryResult , err := p . db . Query ( query , & gocb . QueryOptions {
2023-01-17 20:08:00 +00:00
Context : ctx ,
ScanConsistency : gocb . QueryScanConsistencyRequestPlus ,
NamedParameters : params ,
} )
if err != nil {
return nil , err
}
2023-03-26 01:50:45 +00:00
webhooks := [ ] * model . Webhook { }
for queryResult . Next ( ) {
2023-07-31 11:12:11 +00:00
var webhook * models . Webhook
2023-03-26 01:50:45 +00:00
err := queryResult . Row ( & webhook )
if err != nil {
log . Fatal ( err )
}
webhooks = append ( webhooks , webhook . AsAPIWebhook ( ) )
}
2023-03-29 01:36:33 +00:00
if err := queryResult . Err ( ) ; err != nil {
return nil , err
}
2023-03-26 01:50:45 +00:00
return webhooks , nil
2023-01-17 20:08:00 +00:00
}
// DeleteWebhook to delete webhook
func ( p * provider ) DeleteWebhook ( ctx context . Context , webhook * model . Webhook ) error {
params := make ( map [ string ] interface { } , 1 )
params [ "webhook_id" ] = webhook . ID
removeOpt := gocb . RemoveOptions {
Context : ctx ,
}
_ , err := p . db . Collection ( models . Collections . Webhook ) . Remove ( webhook . ID , & removeOpt )
if err != nil {
return err
}
query := fmt . Sprintf ( ` DELETE FROM %s.%s WHERE webhook_id=$webhook_id ` , p . scopeName , models . Collections . WebhookLog )
_ , err = p . db . Query ( query , & gocb . QueryOptions {
Context : ctx ,
ScanConsistency : gocb . QueryScanConsistencyRequestPlus ,
NamedParameters : params ,
} )
if err != nil {
return err
}
return nil
}