-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from Sam-Martin/feature/dynamodb
DynamoDB
- Loading branch information
Showing
18 changed files
with
628 additions
and
402 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
stage: dev | ||
public_bucket_name: ephemera-public-sammartin-${self:custom.config.stage} | ||
dynamodb_table_name: ephemera-${self:custom.config.stage} | ||
region: eu-west-2 | ||
max_secret_age_hours: "24" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,52 @@ | ||
if(!$stage){ | ||
if(!$stage){ | ||
$stage = 'dev' | ||
} | ||
|
||
# Get endpoint URL | ||
Push-Location serverless-ephemera | ||
$ServerlessInfo = &"serverless" "info" "--stage" $stage | Out-String | ||
Pop-Location | ||
|
||
$ConfigFile = Get-Content 'serverless-ephemera\config.yml' | Out-String | ||
$ConfigFile = Get-Content 'config.yml' | Out-String | ||
$Config = ConvertFrom-Yaml -Yaml $ConfigFile | ||
|
||
$global:PublicWebsite = "http://{0}.s3-website-{1}.amazonaws.com" -f $config.public_bucket_name, $config.region | ||
|
||
$global:addTextSecret = ($ServerlessInfo | select-string 'POST - (https://.*)').Matches[0].Groups[1].Value | ||
$global:getTextSecret = ($ServerlessInfo | select-string 'GET - (https://.*)').Matches[0].Groups[1].Value | ||
$global:PublicWebsite = "http://{0}.s3-website.{1}.amazonaws.com" -f $config.public_bucket_name, $config.region | ||
$global:PublicWebsite = $global:PublicWebsite -replace "\`${self:custom.config.stage}", $config.stage | ||
$ServerlessInfo -match 'POST - (?<url>.*/v2)' | Out-Null | ||
$APIUrl = $Matches.url | ||
|
||
Write-Verbose "Checking stage: $stage" | ||
Write-Verbose "Checking API URL: $APIUrl" | ||
Write-Verbose "Checking API URL: $addTextSecret and $getTextSecret" | ||
|
||
Describe "Ephemera" { | ||
It "Returns a valid secret url!" { | ||
$global:TestSecret = "I am a secret, ssh!" | ||
$Payload = @{secretText = $TestSecret} | ConvertTo-Json | ||
$global:AddSecretResult = (Invoke-WebRequest -uri "$APIUrl/addTextSecret" -Body $Payload -UseBasicParsing -Method POST -ContentType "Application/JSON" -verbose).Content | ConvertFrom-Json | ||
$AddSecretResult.Key | Should match '[\d\w]{8}-[\d\w]{4}-[\d\w]{4}-[\d\w]{4}-[\d\w]{12}' | ||
$global:AddSecretResult = (Invoke-WebRequest -uri $global:addTextSecret -Body $Payload -UseBasicParsing -Method POST -ContentType "Application/JSON" -verbose).Content | ConvertFrom-Json | ||
$global:AddSecretResult.Key | Should match '[\d\w]{8}-[\d\w]{4}-[\d\w]{4}-[\d\w]{4}-[\d\w]{12}' | ||
} | ||
It "Should return the correct secret!" { | ||
$GetSecretResult = (Invoke-WebRequest -uri "$APIUrl/getSecret?key=$($AddSecretResult.Key)" -UseBasicParsing -Method GET -verbose).Content | ConvertFrom-Json | ||
$GetSecretResult.body | Should Be $TestSecret | ||
$Parameters = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) | ||
$Parameters['key'] = $global:AddSecretResult.Key | ||
$Request = [System.UriBuilder]$global:getTextSecret | ||
$Request.Query = $Parameters.ToString() | ||
$GetSecretResult = ([char[]](Invoke-WebRequest -uri $request.uri -Method GET -UseBasicParsing -verbose).Content -join '') | ConvertFrom-Json | ||
$GetSecretResult.secretText | Should Be $TestSecret | ||
} | ||
It "Should NOT return the correct secret twice!" { | ||
$GetSecretResult = (Invoke-WebRequest -uri "$APIUrl/getSecret?key=$($AddSecretResult.Key)" -UseBasicParsing -Method GET -verbose).Content | ConvertFrom-Json | ||
$GetSecretResult.body | Should Not Be $TestSecret | ||
|
||
$Parameters = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) | ||
$Parameters['key'] = $global:AddSecretResult.Key | ||
$Request = [System.UriBuilder]$global:getTextSecret | ||
$Request.Query = $Parameters.ToString() | ||
$GetSecretResult = ([char[]](Invoke-WebRequest -uri $request.uri -Method GET -UseBasicParsing -verbose).Content -join '') | ConvertFrom-Json | ||
$GetSecretResult.secretText | Should Not Be $TestSecret | ||
} | ||
It "Should return a 200 on the public URL" { | ||
(Invoke-WebRequest $global:PublicWebsite -UseBasicParsing).StatusCode | Should Be 200 | ||
} | ||
It "Should have the API URL in the front end config js" { | ||
(Invoke-WebRequest $global:PublicWebsite/js/frontend_config.js -UseBasicParsing).content | Should match $APIUrl | ||
It "Should have the API URL in the front end config json" { | ||
|
||
$Request = [System.UriBuilder]($global:PublicWebsite+"/js/config.json") | ||
$GetConfig = Invoke-RestMethod -uri $request.uri -Method GET -UseBasicParsing | ||
$GetConfig.apiUrl.length | should BeGreaterThan 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,105 @@ | ||
var valuesSet; | ||
// Stolen from http://stackoverflow.com/questions/4656843/jquery-get-querystring-from-url | ||
// Read a page's GET URL variables and return them as an associative array. | ||
function getUrlVars() { | ||
var vars = [], hash; | ||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); | ||
for (var i = 0; i < hashes.length; i++) { | ||
hash = hashes[i].split('='); | ||
vars.push(hash[0]); | ||
vars[hash[0]] = hash[1]; | ||
} | ||
return vars; | ||
var vars = [], | ||
hash; | ||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); | ||
for (var i = 0; i < hashes.length; i++) { | ||
hash = hashes[i].split('='); | ||
vars.push(hash[0]); | ||
vars[hash[0]] = hash[1]; | ||
} | ||
return vars; | ||
} | ||
var populateSecretURL = function (secretURL) { | ||
$('#secretURL').text(secretURL); | ||
|
||
// Clear out the secret field | ||
$('#secret-text').val(''); | ||
|
||
// Slide down the output | ||
$('#secretOutput').slideDown(); | ||
}; | ||
$(document).ready(function () { | ||
|
||
urlVars = getUrlVars(); | ||
if (typeof urlVars != 'undefined' && urlVars.bucket) { | ||
|
||
// if bucket is defined as a GET variable we've just uploaded something | ||
populateSecretURL(window.location.origin + '?key=' + urlVars.key); | ||
} else if(typeof urlVars != 'undefined' && window.location.href.match(/getSecret.html/)){ | ||
var populateSecretURL = function(secretURL) { | ||
$('#secretURL').text(secretURL); | ||
|
||
// Clear out the secret field | ||
$('#secret-text').val(''); | ||
|
||
// if we don't have a secret key, but we're on getSecret.html, tell the user they can't do anything useful here | ||
$('#secretOutput').html('<div class="alert alert-danger" role="alert"><strong>Error:</strong> No secret key defined. If you\'re trying to upload a secret, you may not have access to do so.</html>'); | ||
|
||
// Slide down the output | ||
$('#secretOutput').slideDown(); | ||
}; | ||
$(document).ready(function() { | ||
|
||
populateDom() | ||
}); | ||
|
||
var populateDom = function() { | ||
urlVars = getUrlVars(); | ||
if (typeof urlVars != 'undefined' && urlVars.bucket) { | ||
|
||
} else if (typeof urlVars != 'undefined' && urlVars.key) { | ||
|
||
// if bucket is defined as a GET variable we've just uploaded something | ||
populateSecretURL(window.location.origin + '?key=' + urlVars.key); | ||
} else if (typeof urlVars != 'undefined' && window.location.href.match(/getSecret.html/)) { | ||
|
||
// if we don't have a secret key, but we're on getSecret.html, tell the user they can't do anything useful here | ||
$('#secretOutput').html(`<div class="alert alert-danger" role="alert"> | ||
<strong>Error:</strong> | ||
No secret key defined. If you\'re trying to upload a secret, you may not have access to do so.</html> | ||
`); | ||
|
||
// Slide down the output | ||
$('#secretOutput').slideDown(); | ||
|
||
} else if (typeof urlVars != 'undefined' && urlVars.key) { | ||
getSecret(); | ||
} | ||
|
||
// Upload a string | ||
$('#text-form').submit(uploadSecret); | ||
} | ||
|
||
var uploadSecret = function(ev) { | ||
ev.preventDefault(); | ||
if ($('#secret-text').val().length == 0) { | ||
return | ||
} | ||
$('#secret-text').prop('disabled', true); | ||
$('#text-form > :submit').prop('disabled', true).val('Please Wait...'); | ||
getConfig(function(config) { | ||
var post_addr = config['apiUrl'] + '/addTextSecret' | ||
console.log(post_addr) | ||
$.ajax({ | ||
url: post_addr, | ||
method: 'POST', | ||
data: JSON.stringify({ | ||
'secretText': $('#secret-text').val() | ||
}), | ||
contentType: "application/json" | ||
}).done(function(result) { | ||
$('#secret-text').prop('disabled', false); | ||
$('#text-form > :submit').prop('disabled', false).val('Submit'); | ||
if (result.ErrorMessage) { | ||
alert(result.ErrorMessage); | ||
} else { | ||
populateSecretURL(window.location.origin + '?key=' + result.key); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
var getSecret = function() { | ||
// if key is defined without bucket then we're retrieving a secret | ||
var secretArea = $('#pageBody'); | ||
$('#pageSubtitle p').text('Displaying a secret once...'); | ||
secretArea.html('<h1>Loading Secret...</h1>'); | ||
$.get($.apiUrl + '/getSecret', { key: urlVars.key }, function (result) { | ||
secretArea.html('<h1>Secret</h1>'); | ||
if (result.errorMessage) { | ||
secretArea.append('Secret no longer exists'); | ||
} else if (result['Content-Type'] == 'text/plain') { | ||
secretArea.append("<pre>"+result.body+"</pre>"); | ||
} | ||
getConfig(function(config) { | ||
$.get(config.apiUrl + '/getSecret', { | ||
key: urlVars.key | ||
}, function(result) { | ||
secretArea.html('<h1>Secret</h1>'); | ||
if (result.message) { | ||
secretArea.append(result.message); | ||
} else { | ||
secretArea.append($('<pre>').text(result.secretText)); | ||
} | ||
}, 'json'); | ||
}); | ||
} | ||
|
||
} | ||
|
||
// Upload a string | ||
$('#text-form').submit(function (ev) { | ||
ev.preventDefault(); | ||
$.ajax({ | ||
url: $.apiUrl + '/addTextSecret', | ||
method: 'post', | ||
data: JSON.stringify({ 'secretText': $('#secret-text').val() }), | ||
contentType: "application/json" | ||
|
||
}).done(function (result) { | ||
if(result.ErrorMessage){ | ||
alert(result.ErrorMessage); | ||
} else { | ||
populateSecretURL(window.location.origin + '?key=' + result.key); | ||
} | ||
}); | ||
}); | ||
}); | ||
var getConfig = function(callback) { | ||
$.getJSON('js/config.json', callback) | ||
} |
Oops, something went wrong.