7 Commits
0.2.4 ... 0.2.5

Author SHA1 Message Date
526d29bef1 0.2.5 2022-07-31 02:31:37 +03:00
d08349f800 fix return code style 2022-07-31 02:25:56 +03:00
70a2e47727 add functions module 2022-07-31 02:23:58 +03:00
626e7cbe0b separate source file 2022-07-31 01:40:30 +03:00
5152598804 add input timeout 2022-07-31 01:20:23 +03:00
b8de2dd0b8 change section level 2022-07-26 23:11:37 +03:00
0ff3a7da59 restore emoji 2022-07-26 20:25:40 +03:00
10 changed files with 240 additions and 202 deletions

View File

@@ -6,6 +6,10 @@
- - Information
- ♻️ - Edited
## 0.2.5 - [31/07/2022]
- - Added timeout user input
- ♻️ - Source file separated
## 0.2.4 - [26/07/2022]
- - Added hint for fix file permissions error.
- - Crystal version raise to 1.5.0 for NO_COLOR support

View File

@@ -1,18 +1,17 @@
# The very simple password manager for humans
![pmng](./.docs/logo.png)
# 🔑 The very simple password manager for humans
![License](https://img.shields.io/badge/license-public_domain-brightgreen?style=for-the-badge&color=ffcc68)
![NO_COLOR](https://img.shields.io/badge/no__color-support-brightgreen?style=for-the-badge&color=d44e52)
![Emojy](https://img.shields.io/badge/emojy-like-brightgreen?style=for-the-badge&color=ec8a4b)
![Emoji](https://img.shields.io/badge/emoji-like-brightgreen?style=for-the-badge&color=ec8a4b)
[![Download](https://img.shields.io/badge/Download-brightgreen?style=for-the-badge&color=38607c)](#download)
# Screenshots
## 📷 Screenshots
![pmng](./.docs/logo.png)
![Passwords](./.docs/passwords.png)
# Download
**Coming soon**
## 💾 Download
- [Linux x86_64](https://me.a2s.su/.../)
- [Linux x86](https://me.a2s.su/.../)

View File

@@ -1,5 +1,5 @@
name: pmng
version: 0.2.4
version: 0.2.5
authors:
- Alexander Popov <iiiypuk@iiiypuk.me>

View File

@@ -2,115 +2,53 @@ require "option_parser"
require "yaml"
require "colorize"
# password serializer
class Password
include YAML::Serializable
require "./pmng/*"
require "./pmng/functions/*"
@[YAML::Field(key: "url")]
property url : String
@[YAML::Field(key: "email")]
property email : String
@[YAML::Field(key: "login")]
property login : String
@[YAML::Field(key: "password")]
property password : String
@[YAML::Field(key: "desc")]
property desc : String
@[YAML::Field(key: "profile_url")]
property profile_url : String
@[YAML::Field(key: "update")]
property update : Int32
end
VERSION = "0.2.4"
PASSWORD_FILE_PATH = "#{ENV["HOME"]}/.pwd.yml"
ASCII_LOGO = "
██████╗ ███╗ ███╗███╗ ██╗ ██████╗
██╔══██╗████╗ ████║████╗ ██║██╔════╝
██████╔╝██╔████╔██║██╔██╗ ██║██║ ███╗
██╔═══╝ ██║╚██╔╝██║██║╚██╗██║██║ ██║
██║ ██║ ╚═╝ ██║██║ ╚████║╚██████╔╝
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
"
# program options
begin
OptionParser.parse do |parser|
parser.banner = "The very simple password manager for humans\n"
parser.on "-v", "--version", "Show version" do
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans.".colorize(:yellow)
print "Version ".colorize(:yellow)
puts VERSION.colorize(:red).mode(:bold)
print "\nURL to full change log: ".colorize(:yellow)
puts "https://git.a2s.su/iiiypuk/pmng/raw/branch/master/HISTORY.md".colorize(:green).mode(:bold)
exit(0)
end
parser.on "-h", "--help", "Show help" do
puts parser
exit(0)
end
parser.on "-g", "--generate-password", "Generate password" do
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:black).back(:white)
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:blue)
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:red)
exit(0)
end
parser.on "-t", "--unixtime", "Return local timestamp" do
puts Time.local.to_unix.colorize(:yellow).mode(:bold)
exit(0)
end
end
rescue ex
puts ex.message, ""
end
# check password file exists
if File.exists?(PASSWORD_FILE_PATH)
module Pmng
# check password file exists
if File.exists?(PASSWORD_FILE_PATH)
yaml = File.open(PASSWORD_FILE_PATH) do |file|
YAML.parse(file)
end
else
else
print "~/.pwd.yml".colorize(:red).mode(:bold)
puts ": No such file"
exit(1)
end
end
# check file ppermissions
password_file_permissions = File.info(PASSWORD_FILE_PATH).permissions.to_s
# check file ppermissions
password_file_permissions = File.info(PASSWORD_FILE_PATH).permissions.to_s
if /\d{3}/.match(password_file_permissions).try &.[0] != "600"
if /\d{3}/.match(password_file_permissions).try &.[0] != "600"
puts "Password file permissions is not RW for you.".colorize(:red)
print "Execute: ".colorize(:yellow)
print "(chmod 600 ~/.pwd.yml) ".colorize(:green).mode(:bold)
puts "for fix.".colorize(:yellow)
exit(1)
end
end
# fill passwords array
passwords_array = [] of Password
count = 0
while count < yaml.size
# fill passwords array
passwords_array = [] of Password
count = 0
while count < yaml.size
passwords_array << Password.from_yaml(yaml[count].to_yaml)
count += 1
end
end
# pmng title
system "clear"
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans".colorize(:yellow).mode(:bold)
puts "-------------------------------------------".colorize(:yellow).mode(:bold)
# pmng title
system "clear"
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans".colorize(:yellow).mode(:bold)
puts "-------------------------------------------".colorize(:yellow).mode(:bold)
# main loop
loop = true
while loop
statistics = Functions::Statistics.new(passwords_array)
# main loop
loop = true
while loop
# shell prompt
print "Enter URL (".colorize(:white).mode(:bold)
print ":h".colorize(:red).mode(:bold)
@@ -119,7 +57,12 @@ while loop
print " for exit)\n".colorize(:white).mode(:bold)
print "> ".colorize(:green).mode(:bold)
password_string = gets
begin
STDIN.read_timeout = USER_INPUT_TIMEOUT
password_string = STDIN.gets
rescue IO::TimeoutError
loop = false
end
if password_string.to_s == ":q"
# if ':q' to close program
@@ -137,24 +80,13 @@ while loop
elsif password_string.to_s == ":s"
# if ':s' to view Statistics
system "clear"
puts "Statistics\n----------".colorize(:yellow).mode(:bold)
print "All elements: ".colorize(:yellow).mode(:bold)
puts passwords_array.size
puts statistics.size
print "Passwords outdated: ".colorize(:red).mode(:bold)
outdated_count = 0
current_time = Time.local.to_unix
a = [] of String
passwords_array.each do |item|
if item.update + (2629743 * 3) < current_time # 2629743 * 3 -- 3 month
outdated_count += 1
a << item.url
end
end
puts outdated_count
puts statistics.outdated
else
# list search password
system "clear"
@@ -163,33 +95,7 @@ while loop
passwords_array.each do |item|
if item.url.includes?(password_string.to_s)
print "🌐 "
puts item.url.colorize(:magenta).mode(:bold).mode(:underline)
if !item.email.blank?
print "📧 "
puts item.email.colorize(:red)
end
if !item.login.blank?
print "🗿 "
puts item.login.colorize(:yellow)
end
if !item.password.blank?
print "🔐 "
puts item.password.colorize(:red).back(:red)
end
if !item.desc.blank?
print "📄 "
puts item.desc.colorize(:cyan)
end
if !item.profile_url.blank?
print "👦 "
puts item.profile_url.colorize(:green)
end
Functions.show_item(item)
puts "-----".colorize(:dark_gray).mode(:bold)
@@ -205,7 +111,8 @@ while loop
end
puts
end
end
system "clear"
puts "Bye! 👋"
system "clear"
puts "Bye! 👋"
end

35
src/pmng/agrv_options.cr Normal file
View File

@@ -0,0 +1,35 @@
begin
OptionParser.parse do |parser|
parser.banner = "The very simple password manager for humans\n"
parser.on "-v", "--version", "Show version" do
puts ASCII_LOGO.colorize(:yellow)
puts "The very simple password manager for humans.".colorize(:yellow)
print "Version ".colorize(:yellow)
puts VERSION.colorize(:red).mode(:bold)
puts "\nURL to full changes log: ".colorize(:yellow)
puts "https://git.a2s.su/iiiypuk/pmng/raw/branch/master/HISTORY.md".colorize(:green).mode(:bold)
exit(0)
end
parser.on "-h", "--help", "Show help" do
puts parser
exit(0)
end
parser.on "-g", "--generate-password", "Generate password" do
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:black).back(:white)
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:blue)
puts Random::Secure.urlsafe_base64(16, padding: false).colorize(:white).back(:red)
exit(0)
end
parser.on "-t", "--unixtime", "Return local timestamp" do
puts Time.local.to_unix.colorize(:yellow).mode(:bold)
exit(0)
end
end
rescue ex
puts ex.message, ""
end

3
src/pmng/app_settings.cr Normal file
View File

@@ -0,0 +1,3 @@
VERSION = {{ `shards version "#{__DIR__}"`.chomp.stringify }}
PASSWORD_FILE_PATH = "#{ENV["HOME"]}/.pwd.yml"
USER_INPUT_TIMEOUT = 60

8
src/pmng/ascii_logo.cr Normal file
View File

@@ -0,0 +1,8 @@
ASCII_LOGO = "
██████╗ ███╗ ███╗███╗ ██╗ ██████╗
██╔══██╗████╗ ████║████╗ ██║██╔════╝
██████╔╝██╔████╔██║██╔██╗ ██║██║ ███╗
██╔═══╝ ██║╚██╔╝██║██║╚██╗██║██║ ██║
██║ ██║ ╚═╝ ██║██║ ╚████║╚██████╔╝
╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
"

View File

@@ -0,0 +1,33 @@
module Pmng::Functions
extend self
def show_item(password)
print "🌐 "
puts password.url.colorize(:magenta).mode(:bold).mode(:underline)
if !password.email.blank?
print "📧 "
puts password.email.colorize(:red)
end
if !password.login.blank?
print "🗿 "
puts password.login.colorize(:yellow)
end
if !password.password.blank?
print "🔐 "
puts password.password.colorize(:red).back(:red)
end
if !password.desc.blank?
print "📄 "
puts password.desc.colorize(:cyan)
end
if !password.profile_url.blank?
print "👦 "
puts password.profile_url.colorize(:green)
end
end
end

View File

@@ -0,0 +1,31 @@
module Pmng::Functions
class Statistics
getter passwords : Array(Password)
getter outdated : Int32
getter size : Int32
def initialize(@passwords)
@size = passwords.size
outdated_count = 0
current_time = Time.local.to_unix
a = [] of String
@passwords.each do |item|
if item.update + (2629743 * 3) < current_time # 2629743 * 3 -- 3 month
outdated_count += 1
a << item.url
end
end
@outdated = outdated_count
end
def size
@size
end
def outdated
@outdated
end
end
end

View File

@@ -0,0 +1,18 @@
class Password
include YAML::Serializable
@[YAML::Field(key: "url")]
property url : String
@[YAML::Field(key: "email")]
property email : String
@[YAML::Field(key: "login")]
property login : String
@[YAML::Field(key: "password")]
property password : String
@[YAML::Field(key: "desc")]
property desc : String
@[YAML::Field(key: "profile_url")]
property profile_url : String
@[YAML::Field(key: "update")]
property update : Int32
end