Merge pull request #339 from authorizerdev/fix/webhooks
fix: allow multiple hooks for same event
This commit is contained in:
commit
77f34e1149
2
Makefile
2
Makefile
|
@ -51,6 +51,6 @@ test-all-db:
|
||||||
docker rm -vf authorizer_mongodb_db
|
docker rm -vf authorizer_mongodb_db
|
||||||
docker rm -vf authorizer_arangodb
|
docker rm -vf authorizer_arangodb
|
||||||
docker rm -vf dynamodb-local-test
|
docker rm -vf dynamodb-local-test
|
||||||
# docker rm -vf couchbase-local-test
|
docker rm -vf couchbase-local-test
|
||||||
generate:
|
generate:
|
||||||
cd server && go run github.com/99designs/gqlgen generate && go mod tidy
|
cd server && go run github.com/99designs/gqlgen generate && go mod tidy
|
||||||
|
|
|
@ -63,6 +63,7 @@ interface headersValidatorDataType {
|
||||||
interface selecetdWebhookDataTypes {
|
interface selecetdWebhookDataTypes {
|
||||||
[WebhookInputDataFields.ID]: string;
|
[WebhookInputDataFields.ID]: string;
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
||||||
|
@ -86,6 +87,7 @@ const initHeadersValidatorData: headersValidatorDataType = {
|
||||||
|
|
||||||
interface webhookDataType {
|
interface webhookDataType {
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]: headersDataType[];
|
[WebhookInputDataFields.HEADERS]: headersDataType[];
|
||||||
|
@ -98,6 +100,7 @@ interface validatorDataType {
|
||||||
|
|
||||||
const initWebhookData: webhookDataType = {
|
const initWebhookData: webhookDataType = {
|
||||||
[WebhookInputDataFields.EVENT_NAME]: webhookEventNames['User login'],
|
[WebhookInputDataFields.EVENT_NAME]: webhookEventNames['User login'],
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]: '',
|
||||||
[WebhookInputDataFields.ENDPOINT]: '',
|
[WebhookInputDataFields.ENDPOINT]: '',
|
||||||
[WebhookInputDataFields.ENABLED]: true,
|
[WebhookInputDataFields.ENABLED]: true,
|
||||||
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
||||||
|
@ -144,6 +147,9 @@ const UpdateWebhookModal = ({
|
||||||
case WebhookInputDataFields.EVENT_NAME:
|
case WebhookInputDataFields.EVENT_NAME:
|
||||||
setWebhook({ ...webhook, [inputType]: value });
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
break;
|
break;
|
||||||
|
case WebhookInputDataFields.EVENT_DESCRIPTION:
|
||||||
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
|
break;
|
||||||
case WebhookInputDataFields.ENDPOINT:
|
case WebhookInputDataFields.ENDPOINT:
|
||||||
setWebhook({ ...webhook, [inputType]: value });
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
setValidator({
|
setValidator({
|
||||||
|
@ -246,6 +252,8 @@ const UpdateWebhookModal = ({
|
||||||
let params: any = {
|
let params: any = {
|
||||||
[WebhookInputDataFields.EVENT_NAME]:
|
[WebhookInputDataFields.EVENT_NAME]:
|
||||||
webhook[WebhookInputDataFields.EVENT_NAME],
|
webhook[WebhookInputDataFields.EVENT_NAME],
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]:
|
||||||
|
webhook[WebhookInputDataFields.EVENT_DESCRIPTION],
|
||||||
[WebhookInputDataFields.ENDPOINT]:
|
[WebhookInputDataFields.ENDPOINT]:
|
||||||
webhook[WebhookInputDataFields.ENDPOINT],
|
webhook[WebhookInputDataFields.ENDPOINT],
|
||||||
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
|
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
|
||||||
|
@ -402,7 +410,9 @@ const UpdateWebhookModal = ({
|
||||||
<Flex flex="3">
|
<Flex flex="3">
|
||||||
<Select
|
<Select
|
||||||
size="md"
|
size="md"
|
||||||
value={webhook[WebhookInputDataFields.EVENT_NAME]}
|
value={
|
||||||
|
webhook[WebhookInputDataFields.EVENT_NAME].split('-')[0]
|
||||||
|
}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
inputChangehandler(
|
inputChangehandler(
|
||||||
WebhookInputDataFields.EVENT_NAME,
|
WebhookInputDataFields.EVENT_NAME,
|
||||||
|
@ -420,6 +430,30 @@ const UpdateWebhookModal = ({
|
||||||
</Select>
|
</Select>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<Flex
|
||||||
|
width="100%"
|
||||||
|
justifyContent="start"
|
||||||
|
alignItems="center"
|
||||||
|
marginBottom="5%"
|
||||||
|
>
|
||||||
|
<Flex flex="1">Event Description</Flex>
|
||||||
|
<Flex flex="3">
|
||||||
|
<InputGroup size="md">
|
||||||
|
<Input
|
||||||
|
pr="4.5rem"
|
||||||
|
type="text"
|
||||||
|
placeholder="User event"
|
||||||
|
value={webhook[WebhookInputDataFields.EVENT_DESCRIPTION]}
|
||||||
|
onChange={(e) =>
|
||||||
|
inputChangehandler(
|
||||||
|
WebhookInputDataFields.EVENT_DESCRIPTION,
|
||||||
|
e.currentTarget.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
width="100%"
|
width="100%"
|
||||||
justifyContent="start"
|
justifyContent="start"
|
||||||
|
|
|
@ -179,6 +179,7 @@ export const envSubViews = {
|
||||||
|
|
||||||
export enum WebhookInputDataFields {
|
export enum WebhookInputDataFields {
|
||||||
ID = 'id',
|
ID = 'id',
|
||||||
|
EVENT_DESCRIPTION = 'event_description',
|
||||||
EVENT_NAME = 'event_name',
|
EVENT_NAME = 'event_name',
|
||||||
ENDPOINT = 'endpoint',
|
ENDPOINT = 'endpoint',
|
||||||
ENABLED = 'enabled',
|
ENABLED = 'enabled',
|
||||||
|
|
|
@ -118,6 +118,7 @@ export const WebhooksDataQuery = `
|
||||||
_webhooks(params: $params){
|
_webhooks(params: $params){
|
||||||
webhooks{
|
webhooks{
|
||||||
id
|
id
|
||||||
|
event_description
|
||||||
event_name
|
event_name
|
||||||
endpoint
|
endpoint
|
||||||
enabled
|
enabled
|
||||||
|
|
|
@ -56,6 +56,7 @@ interface paginationPropTypes {
|
||||||
interface webhookDataTypes {
|
interface webhookDataTypes {
|
||||||
[WebhookInputDataFields.ID]: string;
|
[WebhookInputDataFields.ID]: string;
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
||||||
|
@ -117,6 +118,7 @@ const Webhooks = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchWebookData();
|
fetchWebookData();
|
||||||
}, [paginationProps.page, paginationProps.limit]);
|
}, [paginationProps.page, paginationProps.limit]);
|
||||||
|
console.log({ webhookData });
|
||||||
return (
|
return (
|
||||||
<Box m="5" py="5" px="10" bg="white" rounded="md">
|
<Box m="5" py="5" px="10" bg="white" rounded="md">
|
||||||
<Flex margin="2% 0" justifyContent="space-between" alignItems="center">
|
<Flex margin="2% 0" justifyContent="space-between" alignItems="center">
|
||||||
|
@ -134,6 +136,7 @@ const Webhooks = () => {
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Event Name</Th>
|
<Th>Event Name</Th>
|
||||||
|
<Th>Event Description</Th>
|
||||||
<Th>Endpoint</Th>
|
<Th>Endpoint</Th>
|
||||||
<Th>Enabled</Th>
|
<Th>Enabled</Th>
|
||||||
<Th>Headers</Th>
|
<Th>Headers</Th>
|
||||||
|
@ -147,7 +150,10 @@ const Webhooks = () => {
|
||||||
style={{ fontSize: 14 }}
|
style={{ fontSize: 14 }}
|
||||||
>
|
>
|
||||||
<Td maxW="300">
|
<Td maxW="300">
|
||||||
{webhook[WebhookInputDataFields.EVENT_NAME]}
|
{webhook[WebhookInputDataFields.EVENT_NAME].split('-')[0]}
|
||||||
|
</Td>
|
||||||
|
<Td maxW="300">
|
||||||
|
{webhook[WebhookInputDataFields.EVENT_DESCRIPTION]}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>{webhook[WebhookInputDataFields.ENDPOINT]}</Td>
|
<Td>{webhook[WebhookInputDataFields.ENDPOINT]}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
|
@ -264,7 +270,7 @@ const Webhooks = () => {
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
<Text flexShrink="0">Go to page:</Text>{' '}
|
<Text>Go to page:</Text>{' '}
|
||||||
<NumberInput
|
<NumberInput
|
||||||
ml={2}
|
ml={2}
|
||||||
mr={8}
|
mr={8}
|
||||||
|
|
|
@ -10,35 +10,42 @@ import (
|
||||||
|
|
||||||
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
|
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
|
||||||
|
|
||||||
|
// Event name has been kept unique as per initial design. But later on decided that we can have
|
||||||
|
// multiple hooks for same event so will be in a pattern `event_name-TIMESTAMP`
|
||||||
|
|
||||||
// Webhook model for db
|
// Webhook model for db
|
||||||
type Webhook struct {
|
type Webhook struct {
|
||||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
||||||
EndPoint string `json:"endpoint" bson:"endpoint" cql:"endpoint" dynamo:"endpoint"`
|
EventDescription string `json:"event_description" bson:"event_description" cql:"event_description" dynamo:"event_description"`
|
||||||
Headers string `json:"headers" bson:"headers" cql:"headers" dynamo:"headers"`
|
EndPoint string `json:"endpoint" bson:"endpoint" cql:"endpoint" dynamo:"endpoint"`
|
||||||
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled" dynamo:"enabled"`
|
Headers string `json:"headers" bson:"headers" cql:"headers" dynamo:"headers"`
|
||||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled" dynamo:"enabled"`
|
||||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsAPIWebhook to return webhook as graphql response object
|
// AsAPIWebhook to return webhook as graphql response object
|
||||||
func (w *Webhook) AsAPIWebhook() *model.Webhook {
|
func (w *Webhook) AsAPIWebhook() *model.Webhook {
|
||||||
headersMap := make(map[string]interface{})
|
headersMap := make(map[string]interface{})
|
||||||
json.Unmarshal([]byte(w.Headers), &headersMap)
|
json.Unmarshal([]byte(w.Headers), &headersMap)
|
||||||
|
|
||||||
id := w.ID
|
id := w.ID
|
||||||
if strings.Contains(id, Collections.Webhook+"/") {
|
if strings.Contains(id, Collections.Webhook+"/") {
|
||||||
id = strings.TrimPrefix(id, Collections.Webhook+"/")
|
id = strings.TrimPrefix(id, Collections.Webhook+"/")
|
||||||
}
|
}
|
||||||
|
// set default title to event name without dot(.)
|
||||||
|
if w.EventDescription == "" {
|
||||||
|
w.EventDescription = strings.Join(strings.Split(w.EventName, "."), " ")
|
||||||
|
}
|
||||||
return &model.Webhook{
|
return &model.Webhook{
|
||||||
ID: id,
|
ID: id,
|
||||||
EventName: refs.NewStringRef(w.EventName),
|
EventName: refs.NewStringRef(w.EventName),
|
||||||
Endpoint: refs.NewStringRef(w.EndPoint),
|
EventDescription: refs.NewStringRef(w.EventDescription),
|
||||||
Headers: headersMap,
|
Endpoint: refs.NewStringRef(w.EndPoint),
|
||||||
Enabled: refs.NewBoolRef(w.Enabled),
|
Headers: headersMap,
|
||||||
CreatedAt: refs.NewInt64Ref(w.CreatedAt),
|
Enabled: refs.NewBoolRef(w.Enabled),
|
||||||
UpdatedAt: refs.NewInt64Ref(w.UpdatedAt),
|
CreatedAt: refs.NewInt64Ref(w.CreatedAt),
|
||||||
|
UpdatedAt: refs.NewInt64Ref(w.UpdatedAt),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ package arangodb
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/arangodb/go-driver"
|
||||||
arangoDriver "github.com/arangodb/go-driver"
|
arangoDriver "github.com/arangodb/go-driver"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -17,8 +19,9 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
||||||
|
@ -32,12 +35,15 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
||||||
meta, err := webhookCollection.UpdateDocument(ctx, webhook.Key, webhook)
|
meta, err := webhookCollection.UpdateDocument(ctx, webhook.Key, webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = meta.Key
|
webhook.Key = meta.Key
|
||||||
webhook.ID = meta.ID.String()
|
webhook.ID = meta.ID.String()
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
|
@ -55,10 +61,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
paginationClone.Total = cursor.Statistics().FullCount()
|
paginationClone.Total = cursor.Statistics().FullCount()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
meta, err := cursor.ReadDocument(ctx, &webhook)
|
meta, err := cursor.ReadDocument(ctx, &webhook)
|
||||||
|
@ -87,13 +91,11 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"webhook_id": webhookID,
|
"webhook_id": webhookID,
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if !cursor.HasMore() {
|
if !cursor.HasMore() {
|
||||||
if webhook.Key == "" {
|
if webhook.Key == "" {
|
||||||
|
@ -110,32 +112,28 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
query := fmt.Sprintf("FOR d in %s FILTER d.event_name LIKE @event_name RETURN d", models.Collections.Webhook)
|
||||||
query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", models.Collections.Webhook)
|
|
||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"event_name": eventName,
|
"event_name": eventName + "%",
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
webhooks := []*model.Webhook{}
|
||||||
for {
|
for {
|
||||||
if !cursor.HasMore() {
|
var webhook models.Webhook
|
||||||
if webhook.Key == "" {
|
if _, err := cursor.ReadDocument(ctx, &webhook); driver.IsNoMoreDocuments(err) {
|
||||||
return nil, fmt.Errorf("webhook not found")
|
// We're done
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
} else if err != nil {
|
||||||
_, err := cursor.ReadDocument(ctx, &webhook)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
@ -145,17 +143,14 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", models.Collections.WebhookLog, models.Collections.WebhookLog)
|
query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", models.Collections.WebhookLog, models.Collections.WebhookLog)
|
||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"webhook_id": webhook.ID,
|
"webhook_id": webhook.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,6 +207,13 @@ func NewProvider() (*provider, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// add event_description to webhook table
|
||||||
|
webhookAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (event_description text);`, KeySpace, models.Collections.Webhook)
|
||||||
|
err = session.Query(webhookAlterQuery).Exec()
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to alter table as column exists: ", err)
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
|
||||||
webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.WebhookLog)
|
webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.WebhookLog)
|
||||||
err = session.Query(webhookLogCollectionQuery).Exec()
|
err = session.Query(webhookLogCollectionQuery).Exec()
|
||||||
|
|
|
@ -19,29 +19,26 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
existingHook, _ := p.GetWebhookByEventName(ctx, webhook.EventName)
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
if existingHook != nil {
|
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+models.Collections.Webhook, webhook.ID, webhook.EventDescription, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
|
||||||
return nil, fmt.Errorf("Webhook with %s event_name already exists", webhook.EventName)
|
|
||||||
}
|
|
||||||
|
|
||||||
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+models.Collections.Webhook, webhook.ID, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
|
|
||||||
err := p.db.Query(insertQuery).Exec()
|
err := p.db.Query(insertQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
bytes, err := json.Marshal(webhook)
|
bytes, err := json.Marshal(webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -54,22 +51,18 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFields := ""
|
updateFields := ""
|
||||||
for key, value := range webhookMap {
|
for key, value := range webhookMap {
|
||||||
if key == "_id" {
|
if key == "_id" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "_key" {
|
if key == "_key" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
updateFields += fmt.Sprintf("%s = null,", key)
|
updateFields += fmt.Sprintf("%s = null,", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
valueType := reflect.TypeOf(value)
|
valueType := reflect.TypeOf(value)
|
||||||
if valueType.Name() == "string" {
|
if valueType.Name() == "string" {
|
||||||
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
|
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
|
||||||
|
@ -79,7 +72,6 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
||||||
}
|
}
|
||||||
updateFields = strings.Trim(updateFields, " ")
|
updateFields = strings.Trim(updateFields, " ")
|
||||||
updateFields = strings.TrimSuffix(updateFields, ",")
|
updateFields = strings.TrimSuffix(updateFields, ",")
|
||||||
|
|
||||||
query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, updateFields, webhook.ID)
|
query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, updateFields, webhook.ID)
|
||||||
err = p.db.Query(query).Exec()
|
err = p.db.Query(query).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -92,24 +84,21 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
webhooks := []*model.Webhook{}
|
webhooks := []*model.Webhook{}
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
|
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
|
||||||
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no offset in cassandra
|
// there is no offset in cassandra
|
||||||
// so we fetch till limit + offset
|
// so we fetch till limit + offset
|
||||||
// and return the results from offset to limit
|
// and return the results from offset to limit
|
||||||
query := fmt.Sprintf("SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.Webhook, pagination.Limit+pagination.Offset)
|
query := fmt.Sprintf("SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.Webhook, pagination.Limit+pagination.Offset)
|
||||||
|
|
||||||
scanner := p.db.Query(query).Iter().Scanner()
|
scanner := p.db.Query(query).Iter().Scanner()
|
||||||
counter := int64(0)
|
counter := int64(0)
|
||||||
for scanner.Next() {
|
for scanner.Next() {
|
||||||
if counter >= pagination.Offset {
|
if counter >= pagination.Offset {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
err := scanner.Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -127,8 +116,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
query := fmt.Sprintf(`SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID)
|
query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID)
|
||||||
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -136,14 +125,19 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name LIKE '%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.Webhook, eventName+"%")
|
||||||
query := fmt.Sprintf(`SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.Webhook, eventName)
|
scanner := p.db.Query(query).Iter().Scanner()
|
||||||
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
webhooks := []*model.Webhook{}
|
||||||
if err != nil {
|
for scanner.Next() {
|
||||||
return nil, err
|
var webhook models.Webhook
|
||||||
|
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
|
|
@ -19,11 +19,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
insertOpt := gocb.InsertOptions{
|
insertOpt := gocb.InsertOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,10 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
bytes, err := json.Marshal(webhook)
|
bytes, err := json.Marshal(webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -50,17 +53,13 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFields, params := GetSetFields(webhookMap)
|
updateFields, params := GetSetFields(webhookMap)
|
||||||
|
|
||||||
query := fmt.Sprintf(`UPDATE %s.%s SET %s WHERE _id='%s'`, p.scopeName, models.Collections.Webhook, updateFields, webhook.ID)
|
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{
|
_, err = p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
NamedParameters: params,
|
NamedParameters: params,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -72,7 +71,6 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
webhooks := []*model.Webhook{}
|
webhooks := []*model.Webhook{}
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["offset"] = paginationClone.Offset
|
params["offset"] = paginationClone.Offset
|
||||||
params["limit"] = paginationClone.Limit
|
params["limit"] = paginationClone.Limit
|
||||||
|
@ -81,7 +79,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
paginationClone.Total = total
|
paginationClone.Total = total
|
||||||
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.Webhook)
|
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)
|
||||||
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
|
@ -110,11 +108,9 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["_id"] = webhookID
|
params["_id"] = webhookID
|
||||||
|
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)
|
||||||
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook)
|
|
||||||
q, err := p.db.Query(query, &gocb.QueryOptions{
|
q, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
|
@ -124,42 +120,42 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = q.One(&webhook)
|
err = q.One(&webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["event_name"] = eventName
|
// 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+"%")
|
||||||
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name=$event_name LIMIT 1`, p.scopeName, models.Collections.Webhook)
|
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
q, err := p.db.Query(query, &gocb.QueryOptions{
|
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
NamedParameters: params,
|
NamedParameters: params,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = q.One(&webhook)
|
webhooks := []*model.Webhook{}
|
||||||
|
for queryResult.Next() {
|
||||||
if err != nil {
|
var webhook models.Webhook
|
||||||
|
err := queryResult.Row(&webhook)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
if err := queryResult.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return webhooks, nil
|
||||||
return webhook.AsAPIWebhook(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
|
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["webhook_id"] = webhook.ID
|
params["webhook_id"] = webhook.ID
|
||||||
removeOpt := gocb.RemoveOptions{
|
removeOpt := gocb.RemoveOptions{
|
||||||
|
|
|
@ -3,28 +3,29 @@ package dynamodb
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/guregu/dynamo"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/guregu/dynamo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddWebhook to add webhook
|
// AddWebhook to add webhook
|
||||||
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
|
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
err := collection.Put(webhook).RunWithContext(ctx)
|
err := collection.Put(webhook).RunWithContext(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -33,11 +34,13 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
|
||||||
|
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
|
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -51,16 +54,13 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
var lastEval dynamo.PagingKey
|
var lastEval dynamo.PagingKey
|
||||||
var iter dynamo.PagingIter
|
var iter dynamo.PagingIter
|
||||||
var iteration int64 = 0
|
var iteration int64 = 0
|
||||||
|
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
scanner := collection.Scan()
|
scanner := collection.Scan()
|
||||||
count, err := scanner.Count()
|
count, err := scanner.Count()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||||
for iter.NextWithContext(ctx, &webhook) {
|
for iter.NextWithContext(ctx, &webhook) {
|
||||||
|
@ -75,9 +75,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
lastEval = iter.LastEvaluatedKey()
|
lastEval = iter.LastEvaluatedKey()
|
||||||
iteration += paginationClone.Limit
|
iteration += paginationClone.Limit
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone.Total = count
|
paginationClone.Total = count
|
||||||
|
|
||||||
return &model.Webhooks{
|
return &model.Webhooks{
|
||||||
Pagination: &paginationClone,
|
Pagination: &paginationClone,
|
||||||
Webhooks: webhooks,
|
Webhooks: webhooks,
|
||||||
|
@ -88,37 +86,29 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
|
|
||||||
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
|
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
return webhook.AsAPIWebhook(), errors.New("no documets found")
|
return webhook.AsAPIWebhook(), errors.New("no documets found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
webhooks := []models.Webhook{}
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
|
err := collection.Scan().Index("event_name").Filter("contains(event_name, ?)", eventName).AllWithContext(ctx, &webhooks)
|
||||||
iter := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Iter()
|
|
||||||
|
|
||||||
for iter.NextWithContext(ctx, &webhook) {
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := iter.Err()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return webhook.AsAPIWebhook(), err
|
return nil, err
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
resWebhooks := []*model.Webhook{}
|
||||||
|
for _, w := range webhooks {
|
||||||
|
resWebhooks = append(resWebhooks, w.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return resWebhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
@ -133,7 +123,6 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
|
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
|
||||||
|
|
||||||
for _, webhookLog := range webhookLogs.WebhookLogs {
|
for _, webhookLog := range webhookLogs.WebhookLogs {
|
||||||
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
|
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package mongodb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -16,11 +18,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
_, err := webhookCollection.InsertOne(ctx, webhook)
|
_, err := webhookCollection.InsertOne(ctx, webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,39 +34,37 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
_, err := webhookCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": webhook.ID}}, bson.M{"$set": webhook}, options.MergeUpdateOptions())
|
_, err := webhookCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": webhook.ID}}, bson.M{"$set": webhook}, options.MergeUpdateOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhooks to list webhook
|
// ListWebhooks to list webhook
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
var webhooks []*model.Webhook
|
webhooks := []*model.Webhook{}
|
||||||
opts := options.Find()
|
opts := options.Find()
|
||||||
opts.SetLimit(pagination.Limit)
|
opts.SetLimit(pagination.Limit)
|
||||||
opts.SetSkip(pagination.Offset)
|
opts.SetSkip(pagination.Offset)
|
||||||
opts.SetSort(bson.M{"created_at": -1})
|
opts.SetSort(bson.M{"created_at": -1})
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
count, err := webhookCollection.CountDocuments(ctx, bson.M{}, options.Count())
|
count, err := webhookCollection.CountDocuments(ctx, bson.M{}, options.Count())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone.Total = count
|
paginationClone.Total = count
|
||||||
|
|
||||||
cursor, err := webhookCollection.Find(ctx, bson.M{}, opts)
|
cursor, err := webhookCollection.Find(ctx, bson.M{}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close(ctx)
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
for cursor.Next(ctx) {
|
for cursor.Next(ctx) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
err := cursor.Decode(&webhook)
|
err := cursor.Decode(&webhook)
|
||||||
|
@ -73,7 +73,6 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
||||||
}
|
}
|
||||||
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model.Webhooks{
|
return &model.Webhooks{
|
||||||
Pagination: &paginationClone,
|
Pagination: &paginationClone,
|
||||||
Webhooks: webhooks,
|
Webhooks: webhooks,
|
||||||
|
@ -92,14 +91,27 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
webhooks := []*model.Webhook{}
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
err := webhookCollection.FindOne(ctx, bson.M{"event_name": eventName}).Decode(&webhook)
|
opts := options.Find()
|
||||||
|
opts.SetSort(bson.M{"created_at": -1})
|
||||||
|
cursor, err := webhookCollection.Find(ctx, bson.M{"event_name": bson.M{
|
||||||
|
"$regex": fmt.Sprintf("^%s", eventName),
|
||||||
|
}}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
defer cursor.Close(ctx)
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var webhook models.Webhook
|
||||||
|
err := cursor.Decode(&webhook)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
@ -109,12 +121,10 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
|
webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
|
||||||
_, err = webhookLogCollection.DeleteMany(nil, bson.M{"webhook_id": webhook.ID}, options.Delete())
|
_, err = webhookLogCollection.DeleteMany(nil, bson.M{"webhook_id": webhook.ID}, options.Delete())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package provider_template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -14,16 +16,21 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +45,7 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ type Provider interface {
|
||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
|
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error)
|
GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error)
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
|
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
@ -14,10 +16,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
res := p.db.Create(&webhook)
|
res := p.db.Create(&webhook)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
return nil, res.Error
|
return nil, res.Error
|
||||||
|
@ -28,33 +31,31 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
result := p.db.Save(&webhook)
|
result := p.db.Save(&webhook)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhooks to list webhook
|
// ListWebhooks to list webhook
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
var webhooks []models.Webhook
|
var webhooks []models.Webhook
|
||||||
|
|
||||||
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
|
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
var total int64
|
var total int64
|
||||||
totalRes := p.db.Model(&models.Webhook{}).Count(&total)
|
totalRes := p.db.Model(&models.Webhook{}).Count(&total)
|
||||||
if totalRes.Error != nil {
|
if totalRes.Error != nil {
|
||||||
return nil, totalRes.Error
|
return nil, totalRes.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
paginationClone.Total = total
|
paginationClone.Total = total
|
||||||
|
|
||||||
responseWebhooks := []*model.Webhook{}
|
responseWebhooks := []*model.Webhook{}
|
||||||
for _, w := range webhooks {
|
for _, w := range webhooks {
|
||||||
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
||||||
|
@ -77,14 +78,17 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhooks []models.Webhook
|
||||||
|
result := p.db.Where("event_name LIKE ?", eventName+"%").Find(&webhooks)
|
||||||
result := p.db.Where("event_name = ?", eventName).First(&webhook)
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
responseWebhooks := []*model.Webhook{}
|
||||||
|
for _, w := range webhooks {
|
||||||
|
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return responseWebhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
|
|
@ -275,13 +275,14 @@ type ComplexityRoot struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
Webhook struct {
|
Webhook struct {
|
||||||
CreatedAt func(childComplexity int) int
|
CreatedAt func(childComplexity int) int
|
||||||
Enabled func(childComplexity int) int
|
Enabled func(childComplexity int) int
|
||||||
Endpoint func(childComplexity int) int
|
Endpoint func(childComplexity int) int
|
||||||
EventName func(childComplexity int) int
|
EventDescription func(childComplexity int) int
|
||||||
Headers func(childComplexity int) int
|
EventName func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
Headers func(childComplexity int) int
|
||||||
UpdatedAt func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
|
UpdatedAt func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
WebhookLog struct {
|
WebhookLog struct {
|
||||||
|
@ -1833,6 +1834,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Webhook.Endpoint(childComplexity), true
|
return e.complexity.Webhook.Endpoint(childComplexity), true
|
||||||
|
|
||||||
|
case "Webhook.event_description":
|
||||||
|
if e.complexity.Webhook.EventDescription == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Webhook.EventDescription(childComplexity), true
|
||||||
|
|
||||||
case "Webhook.event_name":
|
case "Webhook.event_name":
|
||||||
if e.complexity.Webhook.EventName == nil {
|
if e.complexity.Webhook.EventName == nil {
|
||||||
break
|
break
|
||||||
|
@ -2210,7 +2218,8 @@ type GenerateJWTKeysResponse {
|
||||||
|
|
||||||
type Webhook {
|
type Webhook {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String # this is unique string
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@ -2501,6 +2510,7 @@ input ListWebhookLogRequest {
|
||||||
|
|
||||||
input AddWebhookRequest {
|
input AddWebhookRequest {
|
||||||
event_name: String!
|
event_name: String!
|
||||||
|
event_description: String
|
||||||
endpoint: String!
|
endpoint: String!
|
||||||
enabled: Boolean!
|
enabled: Boolean!
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@ -2509,6 +2519,7 @@ input AddWebhookRequest {
|
||||||
input UpdateWebhookRequest {
|
input UpdateWebhookRequest {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@ -10143,6 +10154,8 @@ func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, fie
|
||||||
return ec.fieldContext_Webhook_id(ctx, field)
|
return ec.fieldContext_Webhook_id(ctx, field)
|
||||||
case "event_name":
|
case "event_name":
|
||||||
return ec.fieldContext_Webhook_event_name(ctx, field)
|
return ec.fieldContext_Webhook_event_name(ctx, field)
|
||||||
|
case "event_description":
|
||||||
|
return ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
case "enabled":
|
case "enabled":
|
||||||
|
@ -12201,6 +12214,47 @@ func (ec *executionContext) fieldContext_Webhook_event_name(ctx context.Context,
|
||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Webhook_event_description(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.EventDescription, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Webhook_event_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Webhook",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Webhook_endpoint(ctx, field)
|
fc, err := ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12907,6 +12961,8 @@ func (ec *executionContext) fieldContext_Webhooks_webhooks(ctx context.Context,
|
||||||
return ec.fieldContext_Webhook_id(ctx, field)
|
return ec.fieldContext_Webhook_id(ctx, field)
|
||||||
case "event_name":
|
case "event_name":
|
||||||
return ec.fieldContext_Webhook_event_name(ctx, field)
|
return ec.fieldContext_Webhook_event_name(ctx, field)
|
||||||
|
case "event_description":
|
||||||
|
return ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
case "enabled":
|
case "enabled":
|
||||||
|
@ -14756,7 +14812,7 @@ func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context,
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"event_name", "endpoint", "enabled", "headers"}
|
fieldsInOrder := [...]string{"event_name", "event_description", "endpoint", "enabled", "headers"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -14771,6 +14827,14 @@ func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "event_description":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_description"))
|
||||||
|
it.EventDescription, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -16612,7 +16676,7 @@ func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Conte
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"id", "event_name", "endpoint", "enabled", "headers"}
|
fieldsInOrder := [...]string{"id", "event_name", "event_description", "endpoint", "enabled", "headers"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -16635,6 +16699,14 @@ func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Conte
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "event_description":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_description"))
|
||||||
|
it.EventDescription, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -18513,6 +18585,10 @@ func (ec *executionContext) _Webhook(ctx context.Context, sel ast.SelectionSet,
|
||||||
|
|
||||||
out.Values[i] = ec._Webhook_event_name(ctx, field, obj)
|
out.Values[i] = ec._Webhook_event_name(ctx, field, obj)
|
||||||
|
|
||||||
|
case "event_description":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Webhook_event_description(ctx, field, obj)
|
||||||
|
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
|
|
||||||
out.Values[i] = ec._Webhook_endpoint(ctx, field, obj)
|
out.Values[i] = ec._Webhook_endpoint(ctx, field, obj)
|
||||||
|
|
|
@ -10,10 +10,11 @@ type AddEmailTemplateRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddWebhookRequest struct {
|
type AddWebhookRequest struct {
|
||||||
EventName string `json:"event_name"`
|
EventName string `json:"event_name"`
|
||||||
Endpoint string `json:"endpoint"`
|
EventDescription *string `json:"event_description"`
|
||||||
Enabled bool `json:"enabled"`
|
Endpoint string `json:"endpoint"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Enabled bool `json:"enabled"`
|
||||||
|
Headers map[string]interface{} `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AdminLoginInput struct {
|
type AdminLoginInput struct {
|
||||||
|
@ -387,11 +388,12 @@ type UpdateUserInput struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateWebhookRequest struct {
|
type UpdateWebhookRequest struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
EventName *string `json:"event_name"`
|
EventName *string `json:"event_name"`
|
||||||
Endpoint *string `json:"endpoint"`
|
EventDescription *string `json:"event_description"`
|
||||||
Enabled *bool `json:"enabled"`
|
Endpoint *string `json:"endpoint"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Enabled *bool `json:"enabled"`
|
||||||
|
Headers map[string]interface{} `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
|
@ -461,13 +463,14 @@ type VerifyOTPRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Webhook struct {
|
type Webhook struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
EventName *string `json:"event_name"`
|
EventName *string `json:"event_name"`
|
||||||
Endpoint *string `json:"endpoint"`
|
EventDescription *string `json:"event_description"`
|
||||||
Enabled *bool `json:"enabled"`
|
Endpoint *string `json:"endpoint"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Enabled *bool `json:"enabled"`
|
||||||
CreatedAt *int64 `json:"created_at"`
|
Headers map[string]interface{} `json:"headers"`
|
||||||
UpdatedAt *int64 `json:"updated_at"`
|
CreatedAt *int64 `json:"created_at"`
|
||||||
|
UpdatedAt *int64 `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebhookLog struct {
|
type WebhookLog struct {
|
||||||
|
|
|
@ -168,7 +168,8 @@ type GenerateJWTKeysResponse {
|
||||||
|
|
||||||
type Webhook {
|
type Webhook {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String # this is unique string
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@ -459,6 +460,7 @@ input ListWebhookLogRequest {
|
||||||
|
|
||||||
input AddWebhookRequest {
|
input AddWebhookRequest {
|
||||||
event_name: String!
|
event_name: String!
|
||||||
|
event_description: String
|
||||||
endpoint: String!
|
endpoint: String!
|
||||||
enabled: Boolean!
|
enabled: Boolean!
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@ -467,6 +469,7 @@ input AddWebhookRequest {
|
||||||
input UpdateWebhookRequest {
|
input UpdateWebhookRequest {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
|
|
|
@ -2,7 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/99designs/gqlgen/graphql/handler"
|
"github.com/99designs/gqlgen/graphql/handler"
|
||||||
graph "github.com/authorizerdev/authorizer/server/graph"
|
"github.com/authorizerdev/authorizer/server/graph"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/generated"
|
"github.com/authorizerdev/authorizer/server/graph/generated"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/authorizerdev/authorizer/server/validators"
|
"github.com/authorizerdev/authorizer/server/validators"
|
||||||
|
@ -22,32 +23,32 @@ func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*m
|
||||||
log.Debug("Failed to get GinContext: ", err)
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
log.Debug("Not logged in as super admin")
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !validators.IsValidWebhookEventName(params.EventName) {
|
if !validators.IsValidWebhookEventName(params.EventName) {
|
||||||
log.Debug("Invalid Event Name: ", params.EventName)
|
log.Debug("Invalid Event Name: ", params.EventName)
|
||||||
return nil, fmt.Errorf("invalid event name %s", params.EventName)
|
return nil, fmt.Errorf("invalid event name %s", params.EventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(params.Endpoint) == "" {
|
if strings.TrimSpace(params.Endpoint) == "" {
|
||||||
log.Debug("empty endpoint not allowed")
|
log.Debug("empty endpoint not allowed")
|
||||||
return nil, fmt.Errorf("empty endpoint not allowed")
|
return nil, fmt.Errorf("empty endpoint not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
headerBytes, err := json.Marshal(params.Headers)
|
headerBytes, err := json.Marshal(params.Headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.EventDescription == nil {
|
||||||
|
params.EventDescription = refs.NewStringRef(strings.Join(strings.Split(params.EventName, "."), " "))
|
||||||
|
}
|
||||||
_, err = db.Provider.AddWebhook(ctx, models.Webhook{
|
_, err = db.Provider.AddWebhook(ctx, models.Webhook{
|
||||||
EventName: params.EventName,
|
EventDescription: refs.StringValue(params.EventDescription),
|
||||||
EndPoint: params.Endpoint,
|
EventName: params.EventName,
|
||||||
Enabled: params.Enabled,
|
EndPoint: params.Endpoint,
|
||||||
Headers: string(headerBytes),
|
Enabled: params.Enabled,
|
||||||
|
Headers: string(headerBytes),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Failed to add webhook: ", err)
|
log.Debug("Failed to add webhook: ", err)
|
||||||
|
|
|
@ -28,13 +28,11 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
||||||
log.Debug("Not logged in as super admin")
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
|
webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("failed to get webhook: ", err)
|
log.Debug("failed to get webhook: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
headersString := ""
|
headersString := ""
|
||||||
if webhook.Headers != nil {
|
if webhook.Headers != nil {
|
||||||
headerBytes, err := json.Marshal(webhook.Headers)
|
headerBytes, err := json.Marshal(webhook.Headers)
|
||||||
|
@ -43,17 +41,16 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
||||||
}
|
}
|
||||||
headersString = string(headerBytes)
|
headersString = string(headerBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookDetails := models.Webhook{
|
webhookDetails := models.Webhook{
|
||||||
ID: webhook.ID,
|
ID: webhook.ID,
|
||||||
Key: webhook.ID,
|
Key: webhook.ID,
|
||||||
EventName: refs.StringValue(webhook.EventName),
|
EventName: refs.StringValue(webhook.EventName),
|
||||||
EndPoint: refs.StringValue(webhook.Endpoint),
|
EventDescription: refs.StringValue(webhook.EventDescription),
|
||||||
Enabled: refs.BoolValue(webhook.Enabled),
|
EndPoint: refs.StringValue(webhook.Endpoint),
|
||||||
Headers: headersString,
|
Enabled: refs.BoolValue(webhook.Enabled),
|
||||||
CreatedAt: refs.Int64Value(webhook.CreatedAt),
|
Headers: headersString,
|
||||||
|
CreatedAt: refs.Int64Value(webhook.CreatedAt),
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.EventName != nil && webhookDetails.EventName != refs.StringValue(params.EventName) {
|
if params.EventName != nil && webhookDetails.EventName != refs.StringValue(params.EventName) {
|
||||||
if isValid := validators.IsValidWebhookEventName(refs.StringValue(params.EventName)); !isValid {
|
if isValid := validators.IsValidWebhookEventName(refs.StringValue(params.EventName)); !isValid {
|
||||||
log.Debug("invalid event name: ", refs.StringValue(params.EventName))
|
log.Debug("invalid event name: ", refs.StringValue(params.EventName))
|
||||||
|
@ -61,7 +58,6 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
||||||
}
|
}
|
||||||
webhookDetails.EventName = refs.StringValue(params.EventName)
|
webhookDetails.EventName = refs.StringValue(params.EventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Endpoint != nil && webhookDetails.EndPoint != refs.StringValue(params.Endpoint) {
|
if params.Endpoint != nil && webhookDetails.EndPoint != refs.StringValue(params.Endpoint) {
|
||||||
if strings.TrimSpace(refs.StringValue(params.Endpoint)) == "" {
|
if strings.TrimSpace(refs.StringValue(params.Endpoint)) == "" {
|
||||||
log.Debug("empty endpoint not allowed")
|
log.Debug("empty endpoint not allowed")
|
||||||
|
@ -69,11 +65,12 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
||||||
}
|
}
|
||||||
webhookDetails.EndPoint = refs.StringValue(params.Endpoint)
|
webhookDetails.EndPoint = refs.StringValue(params.Endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Enabled != nil && webhookDetails.Enabled != refs.BoolValue(params.Enabled) {
|
if params.Enabled != nil && webhookDetails.Enabled != refs.BoolValue(params.Enabled) {
|
||||||
webhookDetails.Enabled = refs.BoolValue(params.Enabled)
|
webhookDetails.Enabled = refs.BoolValue(params.Enabled)
|
||||||
}
|
}
|
||||||
|
if params.EventDescription != nil && webhookDetails.EventDescription != refs.StringValue(params.EventDescription) {
|
||||||
|
webhookDetails.EventDescription = refs.StringValue(params.EventDescription)
|
||||||
|
}
|
||||||
if params.Headers != nil {
|
if params.Headers != nil {
|
||||||
headerBytes, err := json.Marshal(params.Headers)
|
headerBytes, err := json.Marshal(params.Headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,12 +80,10 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
||||||
|
|
||||||
webhookDetails.Headers = string(headerBytes)
|
webhookDetails.Headers = string(headerBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Provider.UpdateWebhook(ctx, webhookDetails)
|
_, err = db.Provider.UpdateWebhook(ctx, webhookDetails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model.Response{
|
return &model.Response{
|
||||||
Message: `Webhook updated successfully.`,
|
Message: `Webhook updated successfully.`,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -3,11 +3,13 @@ package test
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +23,6 @@ func addWebhookTest(t *testing.T, s TestSetup) {
|
||||||
h, err := crypto.EncryptPassword(adminSecret)
|
h, err := crypto.EncryptPassword(adminSecret)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
||||||
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
||||||
EventName: eventType,
|
EventName: eventType,
|
||||||
|
@ -35,5 +36,21 @@ func addWebhookTest(t *testing.T, s TestSetup) {
|
||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhook)
|
||||||
assert.NotEmpty(t, webhook.Message)
|
assert.NotEmpty(t, webhook.Message)
|
||||||
}
|
}
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// Allow setting multiple webhooks for same event
|
||||||
|
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
||||||
|
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
||||||
|
EventName: eventType,
|
||||||
|
Endpoint: s.TestInfo.WebhookEndpoint,
|
||||||
|
Enabled: true,
|
||||||
|
EventDescription: refs.NewStringRef(eventType + "-2"),
|
||||||
|
Headers: map[string]interface{}{
|
||||||
|
"x-test": "foo",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, webhook)
|
||||||
|
assert.NotEmpty(t, webhook.Message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,6 @@ func adminSignupTests(t *testing.T, s TestSetup) {
|
||||||
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: "admin123",
|
AdminSecret: "admin123",
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func deleteWebhookTest(t *testing.T, s TestSetup) {
|
||||||
|
|
||||||
// get all webhooks
|
// get all webhooks
|
||||||
webhooks, err := db.Provider.ListWebhook(ctx, model.Pagination{
|
webhooks, err := db.Provider.ListWebhook(ctx, model.Pagination{
|
||||||
Limit: 10,
|
Limit: 20,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
|
@ -42,7 +42,7 @@ func deleteWebhookTest(t *testing.T, s TestSetup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
webhooks, err = db.Provider.ListWebhook(ctx, model.Pagination{
|
webhooks, err = db.Provider.ListWebhook(ctx, model.Pagination{
|
||||||
Limit: 10,
|
Limit: 20,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
|
|
|
@ -23,6 +23,8 @@ func enableAccessTest(t *testing.T, s TestSetup) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,17 +15,18 @@ func forgotPasswordTest(t *testing.T, s TestSetup) {
|
||||||
t.Run(`should run forgot password`, func(t *testing.T) {
|
t.Run(`should run forgot password`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "forgot_password." + s.TestInfo.Email
|
email := "forgot_password." + s.TestInfo.Email
|
||||||
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
assert.NotNil(t, res)
|
||||||
|
forgotPasswordRes, err := resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err, "no errors for forgot password")
|
assert.Nil(t, err, "no errors for forgot password")
|
||||||
|
assert.NotNil(t, forgotPasswordRes)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
|
|
@ -41,21 +41,20 @@ func inviteUserTest(t *testing.T, s TestSetup) {
|
||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: invalidEmailsTest,
|
Emails: invalidEmailsTest,
|
||||||
})
|
})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
// valid test
|
// valid test
|
||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: emails,
|
Emails: emails,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotNil(t, res)
|
assert.NotNil(t, res)
|
||||||
|
|
||||||
// duplicate error test
|
// duplicate error test
|
||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: emails,
|
Emails: emails,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
|
|
||||||
cleanData(emails[0])
|
cleanData(emails[0])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,13 @@ func loginTests(t *testing.T, s TestSetup) {
|
||||||
t.Run(`should login`, func(t *testing.T) {
|
t.Run(`should login`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "login." + s.TestInfo.Email
|
email := "login." + s.TestInfo.Email
|
||||||
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
signUpRes, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, signUpRes)
|
||||||
res, err := resolvers.LoginResolver(ctx, model.LoginInput{
|
res, err := resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
|
@ -30,6 +31,8 @@ func loginTests(t *testing.T, s TestSetup) {
|
||||||
assert.NotNil(t, err, "should fail because email is not verified")
|
assert.NotNil(t, err, "should fail because email is not verified")
|
||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
n, err := utils.EncryptNonce(verificationRequest.Nonce)
|
n, err := utils.EncryptNonce(verificationRequest.Nonce)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, n)
|
assert.NotEmpty(t, n)
|
||||||
|
|
|
@ -20,22 +20,24 @@ func logoutTests(t *testing.T, s TestSetup) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "logout." + s.TestInfo.Email
|
email := "logout." + s.TestInfo.Email
|
||||||
|
|
||||||
_, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
magicLoginRes, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, magicLoginRes)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
accessToken := *verifyRes.AccessToken
|
accessToken := *verifyRes.AccessToken
|
||||||
assert.NotEmpty(t, accessToken)
|
assert.NotEmpty(t, accessToken)
|
||||||
|
|
||||||
claims, err := token.ParseJWTToken(accessToken)
|
claims, err := token.ParseJWTToken(accessToken)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, claims)
|
assert.NotEmpty(t, claims)
|
||||||
|
|
||||||
loginMethod := claims["login_method"]
|
loginMethod := claims["login_method"]
|
||||||
sessionKey := verifyRes.User.ID
|
sessionKey := verifyRes.User.ID
|
||||||
if loginMethod != nil && loginMethod != "" {
|
if loginMethod != nil && loginMethod != "" {
|
||||||
|
|
|
@ -30,6 +30,8 @@ func magicLinkLoginTests(t *testing.T, s TestSetup) {
|
||||||
assert.Nil(t, err, "signup should be successful")
|
assert.Nil(t, err, "signup should be successful")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,24 +29,25 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
||||||
Password: "test",
|
Password: "test",
|
||||||
ConfirmPassword: "test",
|
ConfirmPassword: "test",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
Email: refs.NewStringRef(email),
|
Email: refs.NewStringRef(email),
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
||||||
|
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, true)
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
Email: refs.NewStringRef(email),
|
Email: refs.NewStringRef(email),
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, false)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
|
@ -54,14 +55,16 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid mobile")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
PhoneNumber: "test",
|
PhoneNumber: "test",
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid mobile")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
PhoneNumber: "1234567890",
|
PhoneNumber: "1234567890",
|
||||||
|
@ -77,7 +80,8 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.Error(t, err, "user exists")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
cleanData("1234567890@authorizer.dev")
|
cleanData("1234567890@authorizer.dev")
|
||||||
|
|
|
@ -27,6 +27,8 @@ func profileTests(t *testing.T, s TestSetup) {
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
|
|
@ -44,10 +44,11 @@ func resendOTPTest(t *testing.T, s TestSetup) {
|
||||||
// Using access token update profile
|
// Using access token update profile
|
||||||
s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
|
s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
|
||||||
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
||||||
_, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
updateRes, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
||||||
IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
|
IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, updateRes)
|
||||||
// Resend otp should return error as no initial opt is being sent
|
// Resend otp should return error as no initial opt is being sent
|
||||||
resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{
|
resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{
|
||||||
Email: email,
|
Email: email,
|
||||||
|
@ -87,7 +88,7 @@ func resendOTPTest(t *testing.T, s TestSetup) {
|
||||||
Otp: otp.Otp,
|
Otp: otp.Otp,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, verifyOtpRes)
|
||||||
verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
|
verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
|
||||||
Email: email,
|
Email: email,
|
||||||
Otp: newOtp.Otp,
|
Otp: newOtp.Otp,
|
||||||
|
|
|
@ -19,13 +19,12 @@ func resendVerifyEmailTests(t *testing.T, s TestSetup) {
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
|
_, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Identifier: constants.VerificationTypeBasicAuthSignup,
|
Identifier: constants.VerificationTypeBasicAuthSignup,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@ func resetPasswordTest(t *testing.T, s TestSetup) {
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
|
@ -28,7 +28,7 @@ func resetPasswordTest(t *testing.T, s TestSetup) {
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err, "should get forgot password request")
|
assert.Nil(t, err, "should get forgot password request")
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
Password: "test1",
|
Password: "test1",
|
||||||
|
|
|
@ -23,6 +23,8 @@ func revokeAccessTest(t *testing.T, s TestSetup) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
@ -33,7 +35,7 @@ func revokeAccessTest(t *testing.T, s TestSetup) {
|
||||||
UserID: verifyRes.User.ID,
|
UserID: verifyRes.User.ID,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,13 @@ func sessionTests(t *testing.T, s TestSetup) {
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
accessToken := *verifyRes.AccessToken
|
accessToken := *verifyRes.AccessToken
|
||||||
assert.NotEmpty(t, accessToken)
|
assert.NotEmpty(t, accessToken)
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,14 @@ func signupTests(t *testing.T, s TestSetup) {
|
||||||
ConfirmPassword: s.TestInfo.Password + "s",
|
ConfirmPassword: s.TestInfo.Password + "s",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.NotNil(t, err, "invalid password")
|
||||||
|
assert.Nil(t, res)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: "test",
|
Password: "test",
|
||||||
ConfirmPassword: "test",
|
ConfirmPassword: "test",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.NotNil(t, err, "invalid password")
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
|
@ -37,7 +37,7 @@ func signupTests(t *testing.T, s TestSetup) {
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.NotNil(t, err, "singup disabled")
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
|
@ -48,15 +48,13 @@ func signupTests(t *testing.T, s TestSetup) {
|
||||||
user := *res.User
|
user := *res.User
|
||||||
assert.Equal(t, email, user.Email)
|
assert.Equal(t, email, user.Email)
|
||||||
assert.Nil(t, res.AccessToken, "access token should be nil")
|
assert.Nil(t, res.AccessToken, "access token should be nil")
|
||||||
|
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NotNil(t, err, "should throw duplicate email error")
|
assert.NotNil(t, err, "should throw duplicate email error")
|
||||||
|
assert.Nil(t, res)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, email, verificationRequest.Email)
|
assert.Equal(t, email, verificationRequest.Email)
|
||||||
|
|
|
@ -40,31 +40,49 @@ func cleanData(email string) {
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeUpdateEmail)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeUpdateEmail)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
otp, err := db.Provider.GetOTPByEmail(ctx, email)
|
otp, err := db.Provider.GetOTPByEmail(ctx, email)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteOTP(ctx, otp)
|
err = db.Provider.DeleteOTP(ctx, otp)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteOTP err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbUser, err := db.Provider.GetUserByEmail(ctx, email)
|
dbUser, err := db.Provider.GetUserByEmail(ctx, email)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.Provider.DeleteUser(ctx, dbUser)
|
err = db.Provider.DeleteUser(ctx, dbUser)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteUser err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,12 @@ func updateAllUsersTest(t *testing.T, s TestSetup) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
t.Run("Should update all users", func(t *testing.T) {
|
t.Run("Should update all users", func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
|
|
||||||
users := []models.User{}
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
user := models.User{
|
user := models.User{
|
||||||
Email: fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email),
|
Email: fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email),
|
||||||
SignupMethods: constants.AuthRecipeMethodBasicAuth,
|
SignupMethods: constants.AuthRecipeMethodBasicAuth,
|
||||||
Roles: "user",
|
Roles: "user",
|
||||||
}
|
}
|
||||||
users = append(users, user)
|
|
||||||
u, err := db.Provider.AddUser(ctx, user)
|
u, err := db.Provider.AddUser(ctx, user)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, u)
|
assert.NotNil(t, u)
|
||||||
|
@ -56,12 +53,15 @@ func updateAllUsersTest(t *testing.T, s TestSetup) {
|
||||||
Limit: 20,
|
Limit: 20,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, listUsers)
|
||||||
for _, u := range listUsers.Users {
|
for _, u := range listUsers.Users {
|
||||||
if utils.StringSliceContains(updateIds, u.ID) {
|
if utils.StringSliceContains(updateIds, u.ID) {
|
||||||
assert.False(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
assert.False(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
||||||
} else {
|
} else {
|
||||||
assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
||||||
}
|
}
|
||||||
|
cleanData(u.Email)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,13 @@ func updateProfileTests(t *testing.T, s TestSetup) {
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
|
s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
|
||||||
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
||||||
|
|
||||||
|
|
|
@ -24,45 +24,73 @@ func updateWebhookTest(t *testing.T, s TestSetup) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
// get webhook
|
// get webhook
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhooks)
|
||||||
// it should completely replace headers
|
assert.Equal(t, 2, len(webhooks))
|
||||||
webhook.Headers = map[string]interface{}{
|
for _, webhook := range webhooks {
|
||||||
"x-new-test": "test",
|
// it should completely replace headers
|
||||||
|
webhook.Headers = map[string]interface{}{
|
||||||
|
"x-new-test": "test",
|
||||||
|
}
|
||||||
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
|
ID: webhook.ID,
|
||||||
|
Headers: webhook.Headers,
|
||||||
|
Enabled: refs.NewBoolRef(false),
|
||||||
|
Endpoint: refs.NewStringRef("https://sometest.com"),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, res)
|
||||||
|
assert.NotEmpty(t, res.Message)
|
||||||
}
|
}
|
||||||
|
if len(webhooks) == 0 {
|
||||||
|
// avoid index out of range error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Test updating webhook name
|
||||||
|
w := webhooks[0]
|
||||||
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
ID: webhook.ID,
|
ID: w.ID,
|
||||||
Headers: webhook.Headers,
|
EventName: refs.NewStringRef(constants.UserAccessEnabledWebhookEvent),
|
||||||
Enabled: refs.NewBoolRef(false),
|
|
||||||
Endpoint: refs.NewStringRef("https://sometest.com"),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, res)
|
assert.NotNil(t, res)
|
||||||
assert.NotEmpty(t, res.Message)
|
// Check if webhooks with new name is as per expected len
|
||||||
|
accessWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserAccessEnabledWebhookEvent)
|
||||||
updatedWebhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, updatedWebhook)
|
assert.Equal(t, 3, len(accessWebhooks))
|
||||||
assert.Equal(t, webhook.ID, updatedWebhook.ID)
|
// Revert name change
|
||||||
assert.Equal(t, refs.StringValue(webhook.EventName), refs.StringValue(updatedWebhook.EventName))
|
|
||||||
assert.Len(t, updatedWebhook.Headers, 1)
|
|
||||||
assert.False(t, refs.BoolValue(updatedWebhook.Enabled))
|
|
||||||
for key, val := range updatedWebhook.Headers {
|
|
||||||
assert.Equal(t, val, webhook.Headers[key])
|
|
||||||
}
|
|
||||||
assert.Equal(t, refs.StringValue(updatedWebhook.Endpoint), "https://sometest.com")
|
|
||||||
|
|
||||||
res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
ID: webhook.ID,
|
ID: w.ID,
|
||||||
Headers: webhook.Headers,
|
EventName: refs.NewStringRef(constants.UserDeletedWebhookEvent),
|
||||||
Enabled: refs.NewBoolRef(true),
|
|
||||||
Endpoint: refs.NewStringRef(s.TestInfo.WebhookEndpoint),
|
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, res)
|
assert.NotNil(t, res)
|
||||||
assert.NotEmpty(t, res.Message)
|
updatedWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, updatedWebhooks)
|
||||||
|
assert.Equal(t, 2, len(updatedWebhooks))
|
||||||
|
for _, updatedWebhook := range updatedWebhooks {
|
||||||
|
assert.Contains(t, refs.StringValue(updatedWebhook.EventName), constants.UserDeletedWebhookEvent)
|
||||||
|
assert.Len(t, updatedWebhook.Headers, 1)
|
||||||
|
assert.False(t, refs.BoolValue(updatedWebhook.Enabled))
|
||||||
|
foundUpdatedHeader := false
|
||||||
|
for key, val := range updatedWebhook.Headers {
|
||||||
|
if key == "x-new-test" && val == "test" {
|
||||||
|
foundUpdatedHeader = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.True(t, foundUpdatedHeader)
|
||||||
|
assert.Equal(t, "https://sometest.com", refs.StringValue(updatedWebhook.Endpoint))
|
||||||
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
|
ID: updatedWebhook.ID,
|
||||||
|
Headers: updatedWebhook.Headers,
|
||||||
|
Enabled: refs.NewBoolRef(true),
|
||||||
|
Endpoint: refs.NewStringRef(s.TestInfo.WebhookEndpoint),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, res)
|
||||||
|
assert.NotEmpty(t, res.Message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func usersTest(t *testing.T, s TestSetup) {
|
||||||
|
|
||||||
usersRes, err := resolvers.UsersResolver(ctx, pagination)
|
usersRes, err := resolvers.UsersResolver(ctx, pagination)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
assert.Nil(t, usersRes)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
h, err := crypto.EncryptPassword(adminSecret)
|
h, err := crypto.EncryptPassword(adminSecret)
|
||||||
|
|
|
@ -53,6 +53,8 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
|
||||||
sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
||||||
nonce := uuid.New().String()
|
nonce := uuid.New().String()
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, authToken)
|
||||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
||||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
||||||
|
|
||||||
|
@ -74,8 +76,8 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
|
||||||
Token: authToken.AccessToken.Token,
|
Token: authToken.AccessToken.Token,
|
||||||
Roles: []string{"invalid_role"},
|
Roles: []string{"invalid_role"},
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run(`should validate the refresh token`, func(t *testing.T) {
|
t.Run(`should validate the refresh token`, func(t *testing.T) {
|
||||||
|
|
|
@ -17,17 +17,14 @@ func verificationRequestsTest(t *testing.T, s TestSetup) {
|
||||||
|
|
||||||
t.Run(`should get verification requests with admin secret only`, func(t *testing.T) {
|
t.Run(`should get verification requests with admin secret only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
|
|
||||||
email := "verification_requests." + s.TestInfo.Email
|
email := "verification_requests." + s.TestInfo.Email
|
||||||
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, res)
|
assert.NotNil(t, res)
|
||||||
|
|
||||||
limit := int64(10)
|
limit := int64(10)
|
||||||
page := int64(1)
|
page := int64(1)
|
||||||
pagination := &model.PaginatedInput{
|
pagination := &model.PaginatedInput{
|
||||||
|
@ -39,6 +36,7 @@ func verificationRequestsTest(t *testing.T, s TestSetup) {
|
||||||
|
|
||||||
requests, err := resolvers.VerificationRequestsResolver(ctx, pagination)
|
requests, err := resolvers.VerificationRequestsResolver(ctx, pagination)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
assert.Nil(t, requests)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ func verifyEmailTest(t *testing.T, s TestSetup) {
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, res)
|
||||||
user := *res.User
|
user := *res.User
|
||||||
assert.Equal(t, email, user.Email)
|
assert.Equal(t, email, user.Email)
|
||||||
assert.Nil(t, res.AccessToken, "access token should be nil")
|
assert.Nil(t, res.AccessToken, "access token should be nil")
|
||||||
|
|
|
@ -29,17 +29,20 @@ func webhookLogsTest(t *testing.T, s TestSetup) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Greater(t, len(webhookLogs.WebhookLogs), 1)
|
assert.Greater(t, len(webhookLogs.WebhookLogs), 1)
|
||||||
|
|
||||||
webhooks, err := resolvers.WebhooksResolver(ctx, nil)
|
webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
|
||||||
|
Pagination: &model.PaginationInput{
|
||||||
|
Limit: refs.NewInt64Ref(20),
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, webhooks)
|
assert.NotEmpty(t, webhooks)
|
||||||
|
|
||||||
for _, w := range webhooks.Webhooks {
|
for _, w := range webhooks.Webhooks {
|
||||||
t.Run(fmt.Sprintf("should get webhook for webhook_id:%s", w.ID), func(t *testing.T) {
|
t.Run(fmt.Sprintf("should get webhook for webhook_id:%s", w.ID), func(t *testing.T) {
|
||||||
webhookLogs, err := resolvers.WebhookLogsResolver(ctx, &model.ListWebhookLogRequest{
|
webhookLogs, err := resolvers.WebhookLogsResolver(ctx, &model.ListWebhookLogRequest{
|
||||||
WebhookID: &w.ID,
|
WebhookID: &w.ID,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.GreaterOrEqual(t, len(webhookLogs.WebhookLogs), 1)
|
assert.GreaterOrEqual(t, len(webhookLogs.WebhookLogs), 1, refs.StringValue(w.EventName))
|
||||||
for _, wl := range webhookLogs.WebhookLogs {
|
for _, wl := range webhookLogs.WebhookLogs {
|
||||||
assert.Equal(t, refs.StringValue(wl.WebhookID), w.ID)
|
assert.Equal(t, refs.StringValue(wl.WebhookID), w.ID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,18 +25,20 @@ func webhookTest(t *testing.T, s TestSetup) {
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
// get webhook by event name
|
// get webhook by event name
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhooks)
|
||||||
|
assert.Equal(t, 2, len(webhooks))
|
||||||
res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{
|
for _, webhook := range webhooks {
|
||||||
ID: webhook.ID,
|
res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{
|
||||||
})
|
ID: webhook.ID,
|
||||||
assert.NoError(t, err)
|
})
|
||||||
assert.Equal(t, res.ID, webhook.ID)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, refs.StringValue(res.Endpoint), refs.StringValue(webhook.Endpoint))
|
assert.Equal(t, res.ID, webhook.ID)
|
||||||
assert.Equal(t, refs.StringValue(res.EventName), refs.StringValue(webhook.EventName))
|
assert.Equal(t, refs.StringValue(res.Endpoint), refs.StringValue(webhook.Endpoint))
|
||||||
assert.Equal(t, refs.BoolValue(res.Enabled), refs.BoolValue(webhook.Enabled))
|
// assert.Equal(t, refs.StringValue(res.EventName), refs.StringValue(webhook.EventName))
|
||||||
assert.Len(t, res.Headers, len(webhook.Headers))
|
assert.Equal(t, refs.BoolValue(res.Enabled), refs.BoolValue(webhook.Enabled))
|
||||||
|
assert.Len(t, res.Headers, len(webhook.Headers))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import (
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -21,9 +23,13 @@ func webhooksTest(t *testing.T, s TestSetup) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
webhooks, err := resolvers.WebhooksResolver(ctx, nil)
|
webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
|
||||||
|
Pagination: &model.PaginationInput{
|
||||||
|
Limit: refs.NewInt64Ref(20),
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, webhooks)
|
assert.NotEmpty(t, webhooks)
|
||||||
assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes))
|
assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes)*2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,98 +17,101 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error {
|
func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error {
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, eventName)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting webhook: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, webhook := range webhooks {
|
||||||
|
if !refs.BoolValue(webhook.Enabled) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userBytes, err := json.Marshal(user.AsAPIUser())
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("error marshalling user obj: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userMap := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal(userBytes, &userMap)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("error un-marshalling user obj: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !refs.BoolValue(webhook.Enabled) {
|
reqBody := map[string]interface{}{
|
||||||
return nil
|
"webhook_id": webhook.ID,
|
||||||
}
|
"event_name": eventName,
|
||||||
|
"event_description": webhook.EventDescription,
|
||||||
|
"user": userMap,
|
||||||
|
}
|
||||||
|
|
||||||
userBytes, err := json.Marshal(user.AsAPIUser())
|
if eventName == constants.UserLoginWebhookEvent || eventName == constants.UserSignUpWebhookEvent {
|
||||||
if err != nil {
|
reqBody["auth_recipe"] = authRecipe
|
||||||
log.Debug("error marshalling user obj: ", err)
|
}
|
||||||
return err
|
|
||||||
}
|
|
||||||
userMap := map[string]interface{}{}
|
|
||||||
err = json.Unmarshal(userBytes, &userMap)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("error un-marshalling user obj: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody := map[string]interface{}{
|
requestBody, err := json.Marshal(reqBody)
|
||||||
"event_name": eventName,
|
if err != nil {
|
||||||
"user": userMap,
|
log.Debug("error marshalling requestBody obj: ", err)
|
||||||
}
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if eventName == constants.UserLoginWebhookEvent || eventName == constants.UserSignUpWebhookEvent {
|
// dont trigger webhook call in case of test
|
||||||
reqBody["auth_recipe"] = authRecipe
|
envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
|
||||||
}
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if envKey == constants.TestEnv {
|
||||||
|
_, err := db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
||||||
|
HttpStatus: 200,
|
||||||
|
Request: string(requestBody),
|
||||||
|
Response: string(`{"message": "test"}`),
|
||||||
|
WebhookID: webhook.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("error saving webhook log:", err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
requestBody, err := json.Marshal(reqBody)
|
requestBytesBuffer := bytes.NewBuffer(requestBody)
|
||||||
if err != nil {
|
req, err := http.NewRequest("POST", refs.StringValue(webhook.Endpoint), requestBytesBuffer)
|
||||||
log.Debug("error marshalling requestBody obj: ", err)
|
if err != nil {
|
||||||
return err
|
log.Debug("error creating webhook post request: ", err)
|
||||||
}
|
continue
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
// dont trigger webhook call in case of test
|
if webhook.Headers != nil {
|
||||||
envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
|
for key, val := range webhook.Headers {
|
||||||
if err != nil {
|
req.Header.Set(key, val.(string))
|
||||||
return err
|
}
|
||||||
}
|
}
|
||||||
if envKey == constants.TestEnv {
|
|
||||||
db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
client := &http.Client{Timeout: time.Second * 30}
|
||||||
HttpStatus: 200,
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("error making request: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
responseBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("error reading response: ", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
statusCode := int64(resp.StatusCode)
|
||||||
|
_, err = db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
||||||
|
HttpStatus: statusCode,
|
||||||
Request: string(requestBody),
|
Request: string(requestBody),
|
||||||
Response: string(`{"message": "test"}`),
|
Response: string(responseBytes),
|
||||||
WebhookID: webhook.ID,
|
WebhookID: webhook.ID,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
return nil
|
log.Debug("failed to add webhook log: ", err)
|
||||||
}
|
continue
|
||||||
|
|
||||||
requestBytesBuffer := bytes.NewBuffer(requestBody)
|
|
||||||
req, err := http.NewRequest("POST", refs.StringValue(webhook.Endpoint), requestBytesBuffer)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("error creating webhook post request: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
if webhook.Headers != nil {
|
|
||||||
for key, val := range webhook.Headers {
|
|
||||||
req.Header.Set(key, val.(string))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{Timeout: time.Second * 30}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("error making request: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
responseBytes, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("error reading response: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
statusCode := int64(resp.StatusCode)
|
|
||||||
_, err = db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
|
||||||
HttpStatus: statusCode,
|
|
||||||
Request: string(requestBody),
|
|
||||||
Response: string(responseBytes),
|
|
||||||
WebhookID: webhook.ID,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("failed to add webhook log: ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user