Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add obfuscate activity #53

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions activity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Activities that are very specific to the operation of the Microgateway.
* [jwt](jwt) allows for JSON web token based authentication
* [ratelimiter](ratelimiter) is a rate limiter implementation
* [sqld](sqld) is a SQL injection attack detector
* [obfuscate](obfuscate) is an activity that allows you to obfuscate the required value in the JSON using defined function
45 changes: 45 additions & 0 deletions activity/obfuscatejson/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!--
title: Obfuscate Activity
weight: 4618
-->

# Obfuscate JSON Payload
This activity allows you to obfuscate the required value in the playload of type JSON using defined function.

Eg . If the payload has a field contianing sensitive information; this activity would obfuscate that field.
```{
...
"BookingCreditCard":"41462917261957261",
...
}
becomes
{
...
"BookingCreditCard":"**********7261",
...
}
```
## Installation

### Flogo CLI
```bash
flogo install github.com/microgateway/activity/obfuscatejson
```

## Configuration

### Settings:
| Name | Type | Description
|:--- | :--- | :---
| operation | string | The operation to perform (Allowed values are setLastFour) - **REQUIRED**
| fields | array | The fields of json to obfuscate - **REQUIRED**

### Supoorted Operations
| Name | Description
|:--- | :---
| setLastFour | This operation adds "*" in place of characters of the field except last four.

### Input:
| Name | Type | Description
|:--- | :--- | :---
| payload | string | The message to obfuscate
107 changes: 107 additions & 0 deletions activity/obfuscatejson/activity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package obfusactejson

import (
"bytes"
"strings"

"github.com/project-flogo/core/activity"
"github.com/project-flogo/core/data/metadata"
)

func init() {
_ = activity.Register(&Activity{}, New) //activity.Register(&Activity{}, New) to create instances using factory method 'New'
}

// Function which defines how to obfuscate the value
type obfuscateFunc func(a string) string

var activityMd = activity.ToMetadata(&Settings{}, &Input{}, &Output{})

//New optional factory method, should be used if one activity instance per configuration is desired
func New(ctx activity.InitContext) (activity.Activity, error) {

s := &Settings{}
err := metadata.MapToStruct(ctx.Settings(), s, true)
if err != nil {
return nil, err
}

var op obfuscateFunc

// Set the operation.
if s.Operation == "setLastFour" {
op = setLastFour
}

act := &Activity{settings: s, operation: op}

return act, nil
}

type Activity struct {
settings *Settings
operation obfuscateFunc
}

func (a *Activity) Metadata() *activity.Metadata {
return activityMd
}

func (a *Activity) Eval(ctx activity.Context) (done bool, err error) {

input := &Input{}
err = ctx.GetInputObject(input)
if err != nil {
return true, err
}
payload := input.Payload

// Iterate over the keys for which the obfuscate function should apply.
for _, val := range a.settings.Fields {
payload = obfuscate(a.operation, val.(string), payload)
}

ctx.SetOutput("result", payload)

return true, nil
}

// Onfuscate takes in the obfuscate function, key and the payload
// and returns the string where the value of the key is obfuscated.
func obfuscate(op obfuscateFunc, key, payload string) string {
// Get the index where the key ends.
// Eg "key":"13445". Should return 6.
keyEndIndex := strings.Index(payload, key) + len(key) + 3

//Get the index where the value corresponding to that key ends.
//Eg. with the above eg it should return 12
valEndIndex := keyEndIndex + strings.Index(payload[keyEndIndex+1:], "\"")

//Get the value corresponding to the key.
keyVal := payload[keyEndIndex:valEndIndex]

// Apply obfuscate function.
val := op(keyVal)

// Stich the result
result := payload[:keyEndIndex] + val + payload[valEndIndex:]

return result
}

func setLastFour(val string) string {

var buffer bytes.Buffer

for key, v := range val {
if key < len(val)-3 {
buffer.WriteString("*")
} else {
buffer.WriteString(string(v))
}

}

return buffer.String()

}
43 changes: 43 additions & 0 deletions activity/obfuscatejson/activity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package obfusactejson

import (
"testing"

"github.com/project-flogo/core/activity"
"github.com/project-flogo/core/support/test"
"github.com/stretchr/testify/assert"
)

func TestRegister(t *testing.T) {

ref := activity.GetRef(&Activity{})
act := activity.Get(ref)

assert.NotNil(t, act)
}

var payload string

func TestEval(t *testing.T) {
settings := &Settings{Operation: "setLastFour", Fields: []interface{}{"LoyaltyRewardsNumber", "BookingCreditCard"}}

iCtx := test.NewActivityInitContext(settings, nil)
act, err := New(iCtx)
assert.Nil(t, err)

payload = `{"application/json":{"flightTrack":{"flightId":271143235,"carrier":{"fs":"EK","name":"Emirates","phoneNumber":"1-800-777-3999","active":true},"CustomerProfile":{"FirstName":"Arden","LastName":"Kaur","LoyaltyRewardsNumber":"EK2340983419","BookingCreditCard":"41462917261957261"},"flightNumber":"202","tailNumber":"N774AN","callsign":"EK202","departureAirport":{"fs":"JFK","iata":"JFK","icao":"KJFK","faa":"JFK","name":"John F. Kennedy International Airport","street1":"JFK Airport","street2":"","city":"New York","cityCode":"NYC","stateCode":"NY","postalCode":"11430","countryCode":"US","countryName":"United States","regionName":"North America","timeZoneRegionName":"America/New_York","weatherZone":"NYZ076","localTime":"2020-08-09T14:58:44.106","utcOffsetHours":-4,"latitude":40.642335,"longitude":-73.78817,"elevationFeet":13,"classification":1,"active":true},"arrivalAirport":{"fs":"EK","name":"Dubai International Airport","city":"Dubai","utcOffsetHours":1,"latitude":51.469603,"longitude":-0.453566,"elevationFeet":80,"classification":1,"active":true},"departureDate":{"dateLocal":"2020-08-08T18:10:00.000","dateUtc":"2020-08-08T22:10:00.000Z"},"equipment":"777","delayMinutes":1,"bearing":119.04182593265193,"heading":89.9998044218202,"positions":[{"lon":-0.4657000005245209,"lat":51.47380065917969,"speedMph":154,"altitudeFt":360,"source":"ADS-B","date":"2020-08-09T05:13:13.000Z"},{"lon":-0.46619999408721924,"lat":51.47380065917969,"speedMph":154,"altitudeFt":360,"source":"ADS-B","date":"2020-08-09T05:12:52.000Z"},{"lon":-0.46650001406669617,"lat":51.47380065917969,"speedMph":154,"altitudeFt":360,"source":"ADS-B","date":"2020-08-09T05:12:33.000Z"},{"lon":-0.4668999910354614,"lat":51.47380065917969,"speedMph":154,"altitudeFt":360,"source":"ADS-B","date":"2020-08-09T05:12:23.000Z"}]}}}`

tc := test.NewActivityContext(act.Metadata())
input := &Input{Payload: payload}
err = tc.SetInputObject(input)
assert.Nil(t, err)

done, err := act.Eval(tc)
assert.True(t, done)
assert.Nil(t, err)

val := tc.GetOutput("result")
assert.NotNil(t, val)

assert.Contains(t, val.(string), "*************7261", "It obfuscated the digits of BookingCreditCard")
}
33 changes: 33 additions & 0 deletions activity/obfuscatejson/descriptor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "obfuscatejson-activity",
"type": "flogo:activity",
"version": "0.0.1",
"title": "ObfuscateJSON Activity",
"description": "Obfuscate JSON Activity llows you to obfuscate the required value in the playload of type JSON using defined function.",
"settings": [
{
"name": "operation",
"type": "string",
"required": true,
"allowed": ["setLastFour"]
},
{
"name": "fields",
"type": "array",
"required": true
}
],
"input": [
{
"name": "payload",
"type": "string",
"required": true
}
],
"output": [
{
"name": "result",
"type": "any"
}
]
}
39 changes: 39 additions & 0 deletions activity/obfuscatejson/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package obfusactejson

import "github.com/project-flogo/core/data/coerce"

type Settings struct {
Operation string `md:"operation,required"`
Fields []interface{} `md:"fields,required"`
}

type Input struct {
Payload string `md:"payload"`
}

func (r *Input) FromMap(values map[string]interface{}) error {
payload, _ := coerce.ToString(values["payload"])
r.Payload = payload
return nil
}

func (r *Input) ToMap() map[string]interface{} {
return map[string]interface{}{
"payload": r.Payload,
}
}

type Output struct {
Result interface{} `md:"result"`
}

func (o *Output) FromMap(values map[string]interface{}) error {
o.Result, _ = values["result"]
return nil
}

func (o *Output) ToMap() map[string]interface{} {
return map[string]interface{}{
"result": o.Result,
}
}