diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7564492 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +*pyc diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..113b6eb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Fede Calendino + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..47bd8c0 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +### [Alfred Workflow](https://www.alfredapp.com/workflows/) to generate secure passwords 🔑️ + + +![PWD Gen default](/img/default.png) + + +![PWD Gen example](/img/low.png) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..52db852 Binary files /dev/null and b/icon.png differ diff --git a/img/default.png b/img/default.png new file mode 100644 index 0000000..41ea52e Binary files /dev/null and b/img/default.png differ diff --git a/img/low.png b/img/low.png new file mode 100644 index 0000000..90b344e Binary files /dev/null and b/img/low.png differ diff --git a/info.plist b/info.plist new file mode 100644 index 0000000..5faedcb --- /dev/null +++ b/info.plist @@ -0,0 +1,128 @@ + + + + + bundleid + com.github.fedecalendino.alfred-pwd-gen + category + Tools + connections + + B0B48240-4B88-4DA4-AF4F-B5E62A496B71 + + + destinationuid + 2CE251E4-C48A-4FF4-85B5-9C594E97F8DC + modifiers + 0 + modifiersubtext + + vitoclose + + + + + createdby + Fede Calendino + description + Generate secure passwords 🔑️ + disabled + + name + Password Generator + objects + + + config + + autopaste + + clipboardtext + {query} + ignoredynamicplaceholders + + transient + + + type + alfred.workflow.output.clipboard + uid + 2CE251E4-C48A-4FF4-85B5-9C594E97F8DC + version + 3 + + + config + + alfredfiltersresults + + alfredfiltersresultsmatchmode + 0 + argumenttreatemptyqueryasnil + + argumenttrimmode + 0 + argumenttype + 1 + escaping + 102 + keyword + pwd + queuedelaycustom + 3 + queuedelayimmediatelyinitially + + queuedelaymode + 0 + queuemode + 1 + runningsubtext + + script + python ./src/main.py $@ + scriptargtype + 1 + scriptfile + + subtext + for example: pwd 9 8 7 + title + pwd [letters=10] [digits=5] [symbols=5] + type + 0 + withspace + + + type + alfred.workflow.input.scriptfilter + uid + B0B48240-4B88-4DA4-AF4F-B5E62A496B71 + version + 3 + + + readme + Generate secure passwords 🔑️ + uidata + + 2CE251E4-C48A-4FF4-85B5-9C594E97F8DC + + xpos + 285 + ypos + 25 + + B0B48240-4B88-4DA4-AF4F-B5E62A496B71 + + xpos + 35 + ypos + 25 + + + version + 1.0 + webaddress + https://github.com/fedecalendino/alfred-pwd-gen + + diff --git a/pwd-gen b/pwd-gen new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e2fa962 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +alfred-workflow diff --git a/src/generator.py b/src/generator.py new file mode 100644 index 0000000..d48e0b2 --- /dev/null +++ b/src/generator.py @@ -0,0 +1,37 @@ +import random + +from math import log + + +LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +DIGITS = "0123456789" +SYMBOLS = "!#$%&*+,-.:;<=>?@^_`~|" + + +def generate(letters, digits, symbols): + characters = [] + + for amount, space in [(letters, LETTERS), (digits, DIGITS), (symbols, SYMBOLS)]: + tmp = (random.choice(space) for _ in range(amount)) + characters.extend(tmp) + + random.shuffle(characters) + + return ''.join(characters) + + +def _calc_streght(password): + return len(password) * log(len(set(password)), 2) + + +def streght(password): + if not password: + return 0 + + current = _calc_streght(password) + baseline = _calc_streght(generate(9, 5, 5)) + + if current > baseline: + return 16 + + return int(15 * current/baseline) diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..bc6d36a --- /dev/null +++ b/src/main.py @@ -0,0 +1,63 @@ +# coding=utf-8 + +import sys + +from workflow import Workflow + +import generator + + +def parse_args(args): + values = [10, 5, 5] + + try: + for i, value in enumerate(args): + values[i] = int(value.strip()) + except: + pass + + return values + + +def format_subtitle(letters, digits, symbols, streght): + letters = "{} letter{}".format(letters, "" if letters == 1 else "s") + digits = "{} digit{}".format(digits, "" if digits == 1 else "s") + symbols = "{} symbol{}".format(symbols, "" if symbols == 1 else "s") + + if streght == 0: + streght = 1 + symbol = u"\U00002B1B" # Black Square + elif streght < 4: + symbol = u"\U0001F7E5" # Red Square + elif streght < 7: + symbol = u"\U0001F7E8" # Yellow Square + elif streght < 12: + symbol = u"\U0001F7E9" # Green Square + elif streght < 15: + symbol = u"\U0001F7E9" # Green Square + else: + symbol = u"\U0001F7E6" # Blue Square + + return u" {} | {} | {} | {}".format(symbol * streght, letters, digits, symbols) + + +def main(workflow): + letters, digits, symbols = parse_args(workflow.args) + + password = generator.generate(letters, digits, symbols) + streght = generator.streght(password) + + workflow.add_item( + title=" {}".format(password), + subtitle=format_subtitle(letters, digits, symbols, streght), + arg=password, + copytext=password, + valid=True + ) + + +if __name__ == u"__main__": + wf = Workflow() + wf.run(main) + wf.send_feedback() + sys.exit()