Skip to content

Commit

Permalink
moved code, exported some helper functions (#94)
Browse files Browse the repository at this point in the history
* moved code, exported some helper functions

* updated changelog
  • Loading branch information
kristinapathak authored Mar 25, 2022
1 parent 884ab5a commit 345c320
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 246 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [v0.3.6]
- Exported helper functions related to InternalWebhook struct. [#94](https://github.com/xmidt-org/ancla/pull/94)

## [v0.3.5]
- Changed errorEncoder to log errors. [#90](https://github.com/xmidt-org/ancla/pull/90)
- Fixed webhook request decoder panic; added default validator when none given. [#92](https://github.com/xmidt-org/ancla/pull/92)
Expand Down
90 changes: 90 additions & 0 deletions internalWebhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2022 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package ancla

import (
"crypto/sha256"
"encoding/json"
"fmt"
"math"
"time"

"github.com/xmidt-org/argus/model"
)

type InternalWebhook struct {
PartnerIDs []string
Webhook Webhook
}

func InternalWebhookToItem(now func() time.Time, iw InternalWebhook) (model.Item, error) {
encodedWebhook, err := json.Marshal(iw)
if err != nil {
return model.Item{}, err
}
var data map[string]interface{}

err = json.Unmarshal(encodedWebhook, &data)
if err != nil {
return model.Item{}, err
}

SecondsToExpiry := iw.Webhook.Until.Sub(now()).Seconds()
TTLSeconds := int64(math.Max(0, SecondsToExpiry))

checksum := fmt.Sprintf("%x", sha256.Sum256([]byte(iw.Webhook.Config.URL)))

return model.Item{
Data: data,
ID: checksum,
TTL: &TTLSeconds,
}, nil
}

func ItemToInternalWebhook(i model.Item) (InternalWebhook, error) {
encodedWebhook, err := json.Marshal(i.Data)
if err != nil {
return InternalWebhook{}, err
}
var iw InternalWebhook
err = json.Unmarshal(encodedWebhook, &iw)
if err != nil {
return InternalWebhook{}, err
}
return iw, nil
}

func ItemsToInternalWebhooks(items []model.Item) ([]InternalWebhook, error) {
iws := []InternalWebhook{}
for _, item := range items {
iw, err := ItemToInternalWebhook(item)
if err != nil {
return nil, err
}
iws = append(iws, iw)
}
return iws, nil
}

func InternalWebhooksToWebhooks(iws []InternalWebhook) []Webhook {
w := make([]Webhook, 0, len(iws))
for _, iw := range iws {
w = append(w, iw.Webhook)
}
return w
}
200 changes: 200 additions & 0 deletions internalWebhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/**
* Copyright 2022 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package ancla

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/xmidt-org/argus/model"
)

func TestItemToInternalWebhook(t *testing.T) {
items := getTestItems()
iws := getTestInternalWebhooks()
tcs := []struct {
Description string
InputItem model.Item
ExpectedInternalWebhook InternalWebhook
ShouldErr bool
}{
{
Description: "Err Marshaling",
InputItem: model.Item{
Data: map[string]interface{}{
"cannotUnmarshal": make(chan int),
},
},
ShouldErr: true,
},
{
Description: "Success",
InputItem: items[0],
ExpectedInternalWebhook: iws[0],
},
}

for _, tc := range tcs {
t.Run(tc.Description, func(t *testing.T) {
assert := assert.New(t)
w, err := ItemToInternalWebhook(tc.InputItem)
if tc.ShouldErr {
assert.Error(err)
}
assert.Equal(tc.ExpectedInternalWebhook, w)
})
}
}

func TestInternalWebhookToItem(t *testing.T) {
refTime := getRefTime()
fixedNow := func() time.Time {
return refTime
}
items := getTestItems()
iws := getTestInternalWebhooks()
tcs := []struct {
Description string
InputInternalWebhook InternalWebhook
ExpectedItem model.Item
ShouldErr bool
}{
{
Description: "Expired item",
InputInternalWebhook: getExpiredInternalWebhook(),
ExpectedItem: getExpiredItem(),
},
{
Description: "Happy path",
InputInternalWebhook: iws[0],
ExpectedItem: items[0],
},
}

for _, tc := range tcs {
t.Run(tc.Description, func(t *testing.T) {
assert := assert.New(t)
item, err := InternalWebhookToItem(fixedNow, tc.InputInternalWebhook)
if tc.ShouldErr {
assert.Error(err)
}
assert.Equal(tc.ExpectedItem, item)
})
}
}

func getExpiredItem() model.Item {
var expiresInSecs int64 = 0
return model.Item{
ID: "b3bbc3467366959e0aba3c33588a08c599f68a740fabf4aa348463d3dc7dcfe8",
Data: map[string]interface{}{
"Webhook": map[string]interface{}{
"registered_from_address": "http://original-requester.example.net",
"config": map[string]interface{}{
"url": "http://deliver-here-0.example.net",
"content_type": "application/json",
"secret": "superSecretXYZ",
},
"events": []interface{}{"online"},
"matcher": map[string]interface{}{
"device_id": []interface{}{"mac:aabbccddee.*"},
},
"failure_url": "http://contact-here-when-fails.example.net",
"duration": float64(time.Second.Nanoseconds()),
"until": "1970-01-01T00:00:01Z",
},
"PartnerIDs": []interface{}{},
},
TTL: &expiresInSecs,
}
}

func getExpiredInternalWebhook() InternalWebhook {
return InternalWebhook{
Webhook: Webhook{
Address: "http://original-requester.example.net",
Config: DeliveryConfig{
URL: "http://deliver-here-0.example.net",
ContentType: "application/json",
Secret: "superSecretXYZ",
},
Events: []string{"online"},
Matcher: struct {
DeviceID []string `json:"device_id"`
}{
DeviceID: []string{"mac:aabbccddee.*"},
},
FailureURL: "http://contact-here-when-fails.example.net",
Duration: time.Second,
Until: time.Unix(1, 0).UTC(),
},
PartnerIDs: []string{},
}
}

func getTestInternalWebhooks() []InternalWebhook {
refTime := getRefTime()
return []InternalWebhook{
{
Webhook: Webhook{
Address: "http://original-requester.example.net",
Config: DeliveryConfig{
URL: "http://deliver-here-0.example.net",
ContentType: "application/json",
Secret: "superSecretXYZ",
},
Events: []string{"online"},
Matcher: MetadataMatcherConfig{
DeviceID: []string{"mac:aabbccddee.*"},
},
FailureURL: "http://contact-here-when-fails.example.net",
Duration: 10 * time.Second,
Until: refTime.Add(10 * time.Second),
},
PartnerIDs: []string{"comcast"},
},
{
Webhook: Webhook{
Address: "http://original-requester.example.net",
Config: DeliveryConfig{
ContentType: "application/json",
URL: "http://deliver-here-1.example.net",
Secret: "doNotShare:e=mc^2",
},
Events: []string{"online"},
Matcher: MetadataMatcherConfig{
DeviceID: []string{"mac:aabbccddee.*"},
},

FailureURL: "http://contact-here-when-fails.example.net",
Duration: 20 * time.Second,
Until: refTime.Add(20 * time.Second),
},
PartnerIDs: []string{},
},
}
}

func getRefTime() time.Time {
refTime, err := time.Parse(time.RFC3339, "2021-01-02T15:04:00Z")
if err != nil {
panic(err)
}
return refTime
}
Loading

0 comments on commit 345c320

Please sign in to comment.