Skip to content
Snippets Groups Projects
Commit 44ceb8da authored by Alex Ellis (VMware)'s avatar Alex Ellis (VMware)
Browse files

Add haveibeenpwned sample function


Idea from Matthew Holt, using the haveibeenpwned API to query
whether a password has been found in a data-breach.

Signed-off-by: default avatarAlex Ellis (VMware) <alexellis2@gmail.com>
parent 87cfa097
No related branches found
No related tags found
No related merge requests found
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// API source - https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange
// Idea from Matthew Holt (@mholt6)
package function
import (
"crypto/sha1"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
)
// Handle a serverless request
func Handle(payload []byte) string {
if len(payload) == 0 {
return "Enter a number of characters."
}
hashed := fmt.Sprintf("%X", sha1.Sum(payload))
prefix := hashed[:5]
c := http.Client{}
req, _ := http.NewRequest(http.MethodGet,
fmt.Sprintf("https://api.pwnedpasswords.com/range/%s", prefix), nil)
res, err := c.Do(req)
if err != nil {
return err.Error()
}
var bytesOut []byte
if res.Body != nil {
defer res.Body.Close()
bytesOut, _ = ioutil.ReadAll(res.Body)
}
passwords := string(bytesOut)
foundTimes, findErr := findPassword(passwords, prefix, hashed)
if findErr != nil {
return findErr.Error()
}
result := result{Found: foundTimes}
output, _ := json.Marshal(result)
return string(output)
}
type result struct {
Found int `json:"found"`
}
func findPassword(passwords string, prefix string, hashed string) (int, error) {
foundTimes := 0
for _, passwordLine := range strings.Split(passwords, "\r\n") {
if passwordLine != "" {
parts := strings.Split(passwordLine, ":")
if fmt.Sprintf("%s%s", prefix, parts[0]) == hashed {
var convErr error
foundTimes, convErr = strconv.Atoi(parts[1])
if convErr != nil {
return 0, fmt.Errorf(`Cannot convert value: "%s", error: "%s"\n`, parts[1], convErr)
}
break
}
}
}
return foundTimes, nil
}
package function
import (
"encoding/json"
"testing"
)
func Test_Handle(t *testing.T) {
res := Handle([]byte("test1234"))
result := result{}
err := json.Unmarshal([]byte(res), &result)
if err != nil {
t.Errorf("unable to unmarshal response, error: %s", err)
t.Fail()
}
if result.Found == 0 {
t.Errorf("expected test1234 to be found several times")
t.Fail()
}
}
provider:
name: faas
gateway: http://localhost:8080 # can be a remote server
gateway: http://localhost:8080
functions:
alpinefunction:
lang: dockerfile
handler: ./AlpineFunction
handler: ./alpinefunction
image: functions/alpine:latest
environment:
fprocess: "cat"
pwgen:
lang: dockerfile
handler: ./pwgen
image: functions/pwgen-sample:latest
apikey-secret:
lang: go
handler: ./apikey-secret
image: functions/apikey-secret:0.1
captainsintent:
lang: dockerfile
handler: ./CaptainsIntent
handler: ./captainsintent
image: functions/captainsintent:latest
echo:
lang: dockerfile
handler: ./echo
image: functions/faas-echo:latest
changecolorintent:
lang: dockerfile
handler: ./ChangeColorIntent
handler: ./changecolorintent
image: functions/alexa-leds:latest
chelloworld:
lang: dockerfile
handler: ./CHelloWorld/src
handler: ./chelloworld
image: functions/helloc:latest
dockerhubstats:
lang: dockerfile
handler: ./DockerHubStats
handler: ./dockerhubstats
image: functions/hubstats:latest
echo:
lang: dockerfile
handler: ./echo
image: functions/faas-echo:latest
gif-maker:
lang: dockerfile
handler: ./gif-maker
image: functions/gif-maker:latest
environment:
read_timeout: 60
write_timeout: 60
haveibeenpwned:
lang: go
handler: ./haveibeenpwned
image: haveibeenpwned:latest
hostnameintent:
lang: dockerfile
handler: ./HostnameIntent
handler: ./hostnameintent
image: functions/hostname-intent:latest
markdownrender:
lang: dockerfile
handler: ./MarkdownRender
handler: ./markdownrender
image: functions/markdown-render:latest
nmap:
lang: dockerfile
handler: ./nmap
image: functions/nmap:0.1
nodeinfo:
lang: dockerfile
handler: ./NodeInfo
handler: ./nodeinfo
image: functions/node-info:latest
phantomjs:
lang: dockerfile
handler: ./Phantomjs
handler: ./phantomjs
image: functions/phantomjs:latest
pwgen:
lang: dockerfile
handler: ./pwgen
image: functions/pwgen-sample:latest
resizeimagemagick:
lang: dockerfile
handler: ./ResizeImageMagick
handler: ./resizeimagemagick
image: functions/resizer:latest
sentimentanalysis:
lang: dockerfile
handler: ./SentimentAnalysis
handler: ./sentimentanalysis
image: functions/sentimentanalysis:latest
webhookstash:
lang: dockerfile
handler: ./WebhookStash
handler: ./webhookstash
image: functions/webhookstash:latest
wordcountfunction:
lang: dockerfile
handler: ./WordCountFunction
handler: ./wordcountfunction
image: functions/wordcount:latest
environment:
fprocess: "wc"
nmap:
lang: dockerfile
handler: ./Nmap
image: functions/nmap:0.1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment