mirror of
https://github.com/leon-ai/leon.git
synced 2024-11-27 08:06:03 +03:00
refactor(skill/have_i_been_pwned): from module to skill
This commit is contained in:
parent
3fea149497
commit
9d5ceb03cb
@ -65,6 +65,11 @@
|
||||
],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/utilities/have_i_been_pwned/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/utilities/is_it_down/run",
|
||||
|
@ -25,7 +25,7 @@
|
||||
]
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"no-pwnage": [
|
||||
"no_pwnage": [
|
||||
"Great news, \"%email%\" hasn't been compromised in a data breach.",
|
||||
"\"%email%\" looks good to me!"
|
||||
],
|
||||
@ -41,7 +41,7 @@
|
||||
"I'm checking for a compromised email...",
|
||||
"Trying to verify pwnage status..."
|
||||
],
|
||||
"no-email": [
|
||||
"no_email": [
|
||||
"Please provide one or more email addresses you need me to check."
|
||||
],
|
||||
"errors": [
|
||||
|
@ -25,7 +25,7 @@
|
||||
]
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"no-pwnage": [
|
||||
"no_pwnage": [
|
||||
"Bonne nouvelle, %email% n'a pas été compromis par une violation de données.",
|
||||
"%email% cela me semble correct!"
|
||||
],
|
||||
@ -38,7 +38,7 @@
|
||||
"Je cherche un email compromis.",
|
||||
"Essayer de vérifier le statut de pwnage."
|
||||
],
|
||||
"no-email": [
|
||||
"no_email": [
|
||||
"Veuillez fournir une ou plusieurs adresses électroniques que vous devez vérifier..."
|
||||
],
|
||||
"errors": [
|
||||
|
@ -22,7 +22,7 @@ def run(string, entities):
|
||||
emails = utils.config('emails')
|
||||
|
||||
if not emails:
|
||||
return utils.output('end', 'no-email', utils.translate('no-email'))
|
||||
return utils.output('end', 'no_email', utils.translate('no_email'))
|
||||
|
||||
utils.output('inter', 'checking', utils.translate('checking'))
|
||||
|
||||
@ -38,9 +38,9 @@ def run(string, entities):
|
||||
return utils.output('end', 'blocked', utils.translate('unavailable', { 'website_name': 'Have I Been Pwned' }))
|
||||
elif not breached:
|
||||
if isLastEmail:
|
||||
return utils.output('end', 'no-pwnage', utils.translate('no-pwnage', data))
|
||||
return utils.output('end', 'no_pwnage', utils.translate('no_pwnage', data))
|
||||
else:
|
||||
utils.output('inter', 'no-pwnage', utils.translate('no-pwnage', data))
|
||||
utils.output('inter', 'no_pwnage', utils.translate('no_pwnage', data))
|
||||
else:
|
||||
data['result'] = ''
|
||||
|
||||
|
@ -6,6 +6,6 @@ describe('checker:haveibeenpwned', () => {
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['no-email'])
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['no_email'])
|
||||
})
|
||||
})
|
||||
|
@ -192,31 +192,41 @@ class Brain {
|
||||
|
||||
// Read output
|
||||
this.process.stdout.on('data', (data) => {
|
||||
const obj = JSON.parse(data.toString())
|
||||
const executionTimeEnd = Date.now()
|
||||
const executionTime = executionTimeEnd - executionTimeStart
|
||||
|
||||
if (typeof obj === 'object') {
|
||||
if (obj.output.type === 'inter') {
|
||||
log.title(`${skillFriendlyName} skill`)
|
||||
log.info(data.toString())
|
||||
try {
|
||||
const obj = JSON.parse(data.toString())
|
||||
|
||||
this.interOutput = obj.output
|
||||
if (typeof obj === 'object') {
|
||||
if (obj.output.type === 'inter') {
|
||||
log.title(`${skillFriendlyName} skill`)
|
||||
log.info(data.toString())
|
||||
|
||||
const speech = obj.output.speech.toString()
|
||||
if (!opts.mute) {
|
||||
this.talk(speech)
|
||||
this.interOutput = obj.output
|
||||
|
||||
const speech = obj.output.speech.toString()
|
||||
if (!opts.mute) {
|
||||
this.talk(speech)
|
||||
}
|
||||
speeches.push(speech)
|
||||
} else {
|
||||
output += data
|
||||
}
|
||||
speeches.push(speech)
|
||||
} else {
|
||||
output += data
|
||||
/* istanbul ignore next */
|
||||
reject({
|
||||
type: 'warning',
|
||||
obj: new Error(`The "${skillFriendlyName}" skill from the "${domainFriendlyName}" domain is not well configured. Check the configuration file.`),
|
||||
speeches,
|
||||
executionTime
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const executionTimeEnd = Date.now()
|
||||
const executionTime = executionTimeEnd - executionTimeStart
|
||||
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
reject({
|
||||
type: 'warning',
|
||||
obj: new Error(`The ${skillFriendlyName} skill from the ${domainFriendlyName} domain is not well configured. Check the configuration file.`),
|
||||
type: 'error',
|
||||
obj: new Error(`The "${skillFriendlyName}" skill from the "${domainFriendlyName}" domain isn't returning JSON format.`),
|
||||
speeches,
|
||||
executionTime
|
||||
})
|
||||
|
0
skills/utilities/have_i_been_pwned/README.md
Normal file
0
skills/utilities/have_i_been_pwned/README.md
Normal file
0
skills/utilities/have_i_been_pwned/memory/.gitkeep
Normal file
0
skills/utilities/have_i_been_pwned/memory/.gitkeep
Normal file
53
skills/utilities/have_i_been_pwned/nlu/en.json
Normal file
53
skills/utilities/have_i_been_pwned/nlu/en.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"actions": {
|
||||
"run": {
|
||||
"utterance_samples": [
|
||||
"Has iifeoluwa.ao@gmail.com been pwned?",
|
||||
"Has iifeoluwa.ao@gmail.com been compromised?",
|
||||
"Has iifeoluwa.ao@gmail.com been exposed in a breach?",
|
||||
"Is iifeoluwa.ao@gmail.com still uncompromised?",
|
||||
"Is iifeoluwa.ao@gmail.com compromised?",
|
||||
"Have my email address been pwned?",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been compromised",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been pwned",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been exposed in a breach",
|
||||
"Verify the pwnage status of iifeoluwa.ao@gmail.com",
|
||||
"Verify the pwnage status of iifeoluwa.ao@gmail.com and louis.grenard@gmail.com"
|
||||
]
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"no_pwnage": [
|
||||
"Great news, \"%email%\" hasn't been compromised in a data breach.",
|
||||
"\"%email%\" looks good to me!"
|
||||
],
|
||||
"pwned": [
|
||||
"Oops, looks like \"%email%\" has been compromised in at least one breach involving:<br><br><ul>%result%</ul>",
|
||||
"Sadly, \"%email%\" was affected in the following breaches:<br><br><ul>%result%</ul>",
|
||||
"Unfortunately, \"%email%\" has been exposed in a data breach affecting:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_element": [
|
||||
"<li><a href=\"%url%\" target=\"_blank\">%name%</a> with a total of %total% accounts.</li>"
|
||||
],
|
||||
"checking": [
|
||||
"I'm checking for a compromised email...",
|
||||
"Trying to verify pwnage status..."
|
||||
],
|
||||
"no_email": [
|
||||
"Please provide one or more email addresses you need me to check."
|
||||
],
|
||||
"errors": [
|
||||
"I think %website_name% is down at the moment, please try again later.",
|
||||
"I'm having trouble reaching %website_name%. Please check that your internet connection is active.",
|
||||
"Bad news, %website_name% is not responding. Maybe try at a later time?"
|
||||
],
|
||||
"blocked": [
|
||||
"There was an issue accessing %website_name%'s service.",
|
||||
"Unfortunate news, %website_name% isn't granting me access to its service."
|
||||
],
|
||||
"unavailable": [
|
||||
"It looks like Cloudflare is defending %website_name%, please retry in a few moments.",
|
||||
"Unfortunately, Cloudflare is temporarily blocking your access to %website_name%, please retry in a while."
|
||||
]
|
||||
}
|
||||
}
|
48
skills/utilities/have_i_been_pwned/nlu/fr.json
Normal file
48
skills/utilities/have_i_been_pwned/nlu/fr.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"actions": {
|
||||
"run": {
|
||||
"utterance_samples": [
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été pwned ?",
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été compromise ?",
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été exposée à une brèche ?",
|
||||
"iifeoluwa.ao@gmail.com est-elle toujours non compromise ?",
|
||||
"Est-ce que iifeoluwa.ao@gmail.com est compromise ?",
|
||||
"Est-ce que mon adresse email a été compromise ?",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été compromise",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été pwned",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été exposées à une brèche"
|
||||
]
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"no_pwnage": [
|
||||
"Bonne nouvelle, %email% n'a pas été compromis par une violation de données.",
|
||||
"%email% cela me semble correct!"
|
||||
],
|
||||
"pwned": [
|
||||
"Oups, on dirait que %email% a été compromis par une infraction impliquant %breach%.",
|
||||
"%breach% a été impliqué dans une brèche. Malheureusement, %email% a été touché.",
|
||||
"Malheureusement, %email% a été exposé à une violation de données affectant %breach%."
|
||||
],
|
||||
"checking": [
|
||||
"Je cherche un email compromis.",
|
||||
"Essayer de vérifier le statut de pwnage."
|
||||
],
|
||||
"no_email": [
|
||||
"Veuillez fournir une ou plusieurs adresses électroniques que vous devez vérifier..."
|
||||
],
|
||||
"errors": [
|
||||
"Je pense que %website_name% est en panne pour le moment, veuillez réessayer plus tard.",
|
||||
"J'ai du mal à joindre %website_name%. Veuillez vérifier que votre connexion Internet est active.",
|
||||
"Mauvaise nouvelle, %website_name% ne répond pas. Peut-être essayer plus tard?"
|
||||
],
|
||||
"blocked": [
|
||||
"Il y avait un problème d'accès au service de %website_name%.",
|
||||
"Malheureusement, %website_name% ne me donne pas accès à son service."
|
||||
],
|
||||
"unavailable": [
|
||||
"Il semblerait que Cloudflare protège %website_name%, veuillez réessayer dans un petit instant.",
|
||||
"Malheureusement, Cloudflare a temporairement bloqué votre accès à %website_name%, merci de retenter dans un moment."
|
||||
]
|
||||
}
|
||||
}
|
11
skills/utilities/have_i_been_pwned/skill.json
Normal file
11
skills/utilities/have_i_been_pwned/skill.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Have I Been Pwned",
|
||||
"bridge": "python",
|
||||
"version": "1.0.0",
|
||||
"description": "Verify if one or several email addresses have been pwned (thanks to haveibeenpwned.com).",
|
||||
"author": {
|
||||
"name": "Louis Grenard",
|
||||
"email": "louis.grenard@gmail.com",
|
||||
"url": "https://github.com/louistiti"
|
||||
}
|
||||
}
|
76
skills/utilities/have_i_been_pwned/src/actions/run.py
Normal file
76
skills/utilities/have_i_been_pwned/src/actions/run.py
Normal file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import utils
|
||||
from time import sleep
|
||||
from urllib import parse
|
||||
from requests import codes, exceptions
|
||||
|
||||
# Developer token
|
||||
api_key = utils.config('credentials')['api_key']
|
||||
|
||||
def run(string, entities):
|
||||
"""Verify if one or several email addresses have been pwned"""
|
||||
|
||||
emails = []
|
||||
|
||||
for item in entities:
|
||||
if item['entity'] == 'email':
|
||||
emails.append(item['resolution']['value'])
|
||||
|
||||
if not emails:
|
||||
emails = utils.config('options')['emails']
|
||||
|
||||
if not emails:
|
||||
return utils.output('end', 'no_email', utils.translate('no_email'))
|
||||
|
||||
utils.output('inter', 'checking', utils.translate('checking'))
|
||||
|
||||
for index, email in enumerate(emails):
|
||||
is_last_email = index == len(emails) - 1
|
||||
breached = check_for_breach(email)
|
||||
data = { 'email': email }
|
||||
|
||||
# Have I Been Pwned API returns a 403 when accessed by unauthorized/banned clients
|
||||
if breached == 403:
|
||||
return utils.output('end', 'blocked', utils.translate('blocked', { 'website_name': 'Have I Been Pwned' }))
|
||||
elif breached == 503:
|
||||
return utils.output('end', 'blocked', utils.translate('unavailable', { 'website_name': 'Have I Been Pwned' }))
|
||||
elif not breached:
|
||||
if is_last_email:
|
||||
return utils.output('end', 'no_pwnage', utils.translate('no_pwnage', data))
|
||||
else:
|
||||
utils.output('inter', 'no_pwnage', utils.translate('no_pwnage', data))
|
||||
else:
|
||||
data['result'] = ''
|
||||
|
||||
for index, b in enumerate(breached):
|
||||
data['result'] += utils.translate('list_element', {
|
||||
'url': 'http://' + b['Domain'],
|
||||
'name': b['Name'],
|
||||
'total': b['PwnCount']
|
||||
}
|
||||
)
|
||||
|
||||
if is_last_email:
|
||||
return utils.output('end', 'pwned', utils.translate('pwned', data))
|
||||
else:
|
||||
utils.output('inter', 'pwned', utils.translate('pwned', data))
|
||||
|
||||
def check_for_breach(email):
|
||||
# Delay for 2 seconds before making request to accomodate API usage policy
|
||||
sleep(2)
|
||||
truncate = '?truncateResponse=true'
|
||||
url = 'https://haveibeenpwned.com/api/v3/breachedaccount/' + parse.quote_plus(email)
|
||||
|
||||
try:
|
||||
response = utils.http('GET', url, { 'hibp-api-key': api_key })
|
||||
|
||||
if response.status_code == 404:
|
||||
return None
|
||||
elif response.status_code == 200:
|
||||
return response.json()
|
||||
|
||||
return response.status_code
|
||||
except exceptions.RequestException as e:
|
||||
return utils.output('end', 'down', utils.translate('errors', { 'website_name': 'Have I Been Pwned' }))
|
10
skills/utilities/have_i_been_pwned/src/config.sample.json
Normal file
10
skills/utilities/have_i_been_pwned/src/config.sample.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"configurations": {
|
||||
"options": {
|
||||
"emails": []
|
||||
},
|
||||
"credentials": {
|
||||
"api_key": "YOUR_API_KEY"
|
||||
}
|
||||
}
|
||||
}
|
0
skills/utilities/have_i_been_pwned/src/lib/.gitkeep
Normal file
0
skills/utilities/have_i_been_pwned/src/lib/.gitkeep
Normal file
0
skills/utilities/have_i_been_pwned/test/.gitkeep
Normal file
0
skills/utilities/have_i_been_pwned/test/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user