Skip to content

Commit

Permalink
Release 2.0.1 (#48)
Browse files Browse the repository at this point in the history
* Update Jenkinsfile

* Alpine & Python version update

* Update tips
  • Loading branch information
ytsek authored Jul 13, 2021
1 parent a9c64f0 commit 463d851
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 32 deletions.
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
FROM alpine:3.13
FROM alpine:3.14
LABEL maintainer="Ian Redden <iaredden@cisco.com>"

# install packages we need
RUN apk update && apk add --no-cache musl-dev openssl-dev gcc python3 py3-configobj python3-dev supervisor git libffi-dev uwsgi-python3 uwsgi-http jq nano syslog-ng uwsgi-syslog py3-pip
RUN apk update && apk add --no-cache musl-dev openssl-dev gcc py3-configobj \
supervisor git libffi-dev uwsgi-python3 uwsgi-http jq syslog-ng uwsgi-syslog \
py3-pip python3-dev

# do the Python dependencies
ADD code /app
Expand Down
16 changes: 3 additions & 13 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
pipeline {
agent any
stages {
stage('build&test') {
steps {
sh 'docker build -t tr-05-spycloud-employee-ato-prevention .'
sh 'docker run -d -p 9090:9090 --name tr-05-spycloud-employee-ato-prevention tr-05-spycloud-employee-ato-prevention'
sh 'while true; do if docker logs tr-05-spycloud-employee-ato-prevention | grep "entered RUNNING state"; then break; else sleep 1; fi done'
sh 'curl -X POST -sSLi http://localhost:9090 | grep "200 OK"'
}
}
}
}
@Library('softserve-jenkins-library@main') _

startPipeline()
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ curl http://localhost:9090

## Implementation Details

This application was developed and tested under Python version 3.9.

### Implemented Relay Endpoints

- `POST /health`
Expand Down
4 changes: 3 additions & 1 deletion code/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import requests

from json.decoder import JSONDecodeError
from typing import Optional
from http import HTTPStatus
from flask import request, current_app, jsonify, g
Expand Down Expand Up @@ -56,6 +57,7 @@ def get_public_key(jwks_host, token):
expected_errors = {
ConnectionError: WRONG_JWKS_HOST,
InvalidURL: WRONG_JWKS_HOST,
JSONDecodeError: WRONG_JWKS_HOST,
}
try:
response = requests.get(f"https://{jwks_host}/.well-known/jwks")
Expand Down Expand Up @@ -224,7 +226,7 @@ def wraps(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
pause_time = current_app.config['SPYCLOUD_REQUEST_DURATION'] - (
time.time() - start)
time.time() - start)
if pause_time > 0:
time.sleep(pause_time)
return result
Expand Down
5 changes: 4 additions & 1 deletion code/container_settings.json
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
{"VERSION": "2.0.0","NAME": "Spycloud Employee Ato Prevention Relay"}
{
"VERSION": "2.0.1",
"NAME": "Spycloud Employee Ato Prevention Relay"
}
12 changes: 6 additions & 6 deletions code/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Flask==1.1.2
marshmallow==3.11.1
Flask==2.0.1
marshmallow==3.12.1
requests==2.25.1
cryptography==3.3.2
pyjwt[crypto]==2.0.1
flake8==3.9.0
coverage==5.2.1
pytest==6.2.2
pyjwt[crypto]==2.1.0
flake8==3.9.2
coverage==5.5
pytest==6.2.4
2 changes: 1 addition & 1 deletion code/tests/functional/tests/constants.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MODULE_NAME = 'SpyCloud Account Takeover Prevention [Conf]'
MODULE_NAME = 'SpyCloud Account Takeover Prevention'
SPYCLOUD_URL = 'https://portal.spycloud.com/breach/catalog/'
CONFIDENCE = SEVERITY = ('High', 'Medium', 'Low')
CTR_ENTITIES_LIMIT = 100
Expand Down
5 changes: 4 additions & 1 deletion code/tests/functional/tests/test_sigthing.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ def test_positive_sighting_email_observable(module_headers):
{'name': 'cc_last_four', 'type': 'string'},
{'name': 'address_1', 'type': 'string'},
{'name': 'homepage', 'type': 'string'},
{'name': 'company_name', 'type': 'string'}
{'name': 'company_name', 'type': 'string'},
{'name': 'user_sys_registered_owner', 'type': 'string'},
{'name': 'user_os', 'type': 'string'},
{'name': 'user_hostname', 'type': 'string'}
]
assert len(sightings['docs']) > 0

Expand Down
10 changes: 3 additions & 7 deletions module_type.json.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
"default_name": "SpyCloud ATP",
"short_description": "SpyCloud helps enterprises prevent corporate account takeover by detecting stolen passwords early, before criminals have a chance to use them.",
"description": "It's human nature: people reuse passwords. Unfortunately, your employees' bad password hygiene may put your enterprise at risk of a data breach. According to the 2020 Verizon Data Breach Investigations Report, stolen credentials have been the top hacking technique for four years in a row. Criminals count on employees' password reuse, testing stolen credentials against a variety of other sites - including corporate login portals - to take over accounts and access sensitive customer data, financial information, and intellectual property.\n\n SpyCloud helps enterprises prevent corporate account takeover by detecting exposed credentials quickly, before criminals have a chance to use them against your enterprise. SpyCloud provides fast, high-volume access to stolen data circulating within criminal communities, drawing on a collection and curation platform that has operationalized over 100 billion recovered breach assets for security teams. By checking your employee logins against the largest repository of recovered stolen credentials in the world, you can reset compromised passwords swiftly and safeguard your sensitive corporate assets.",
"tips": "When configuring this integration, you must first gather some information from your SpyCloud account, and then add the SpyCloud Module\n\n1. Log into SpyCloud, click on your **email address** in the top right corner, choose **API Keys**\n2. Click on the **eye icon** next to the Employee ATO Protection **API Key** \n3. Copy the **API Key** into a file, or leave the tab open\n4. Complete the **Add New SpyCloud Module** form:\n - **Module Name** - Leave the default name or enter a name that is meaningful to you\n - Enter the **API Key**\n5. Click **Save** to complete the SpyCloud module configuration",
"tips": "When configuring SpyCloud Account Takeover Prevention integration, you must generate the API key from your SpyCloud account and then add the SpyCloud Account Takeover Prevention integration module in SecureX.\n\n1. Log in to SpyCloud, click your **email address** in the top right corner and choose **API Keys**.\n\n2. Click on the eye icon next to the Employee ATO Protection **API Key** and copy the API key into a file, or leave the tab open.\n4. In SecureX, complete the **Add New SpyCloud Account Takeover Prevention Integration Module** form:\n - **Integration Module Name** - Leave the default name or enter a name that is meaningful to you.\n - **API Key** - Paste your copied API key from SpyCloud into this field.\n - **Entities Limit** - Specify the maximum number of sightings in a single response, per requested observable (must be a positive value). We recommend that you enter a limit in the range of 50 to 1000. The default is 100 entities.\n \n5. Click **Save** to complete the SpyCloud Account Takeover Prevention integration module configuration.",
"external_references": [
{
"label": "Free Trial",
"link": "https://spycloud.com/request-a-demo/?utm_campaign=cisco&utm_source=cisco"
},
{
"label": "Case Study",
"link": "https://spycloud.com/resource/global-networking-company/?utm_campaign=cisco&utm_source=cisco"
Expand All @@ -34,7 +30,7 @@
"key": "custom_CTR_ENTITIES_LIMIT",
"type": "integer",
"label": "Entities Limit",
"tooltip": "Restricts the maximum number of `Sightings`",
"tooltip": "Restricts the maximum number of `Sightings`. Please note that the number over 100 might lead to data inconsistency.",
"required": false
}
],
Expand All @@ -59,4 +55,4 @@
"url": "https://ciscohosted.url"
},
"logo": "data:image/png;base64,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"
}
}

0 comments on commit 463d851

Please sign in to comment.