ptj 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +84 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +96 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/etc/config.yml +23 -0
- data/lib/ptj.rb +5 -0
- data/lib/ptj/default_setup.rb +10 -0
- data/lib/ptj/environment.rb +115 -0
- data/lib/ptj/ext.rb +1 -0
- data/lib/ptj/ext/datamapper_collection.rb +74 -0
- data/lib/ptj/model.rb +65 -0
- data/lib/ptj/model/password.rb +116 -0
- data/lib/ptj/model/tag.rb +19 -0
- data/lib/ptj/model/tasks.rb +38 -0
- data/lib/ptj/parser.rb +1 -0
- data/lib/ptj/parser/fileparser.rb +24 -0
- data/lib/ptj/parser/fileparser/countpassonly.rb +27 -0
- data/lib/ptj/parser/fileparser/hashpassonlycolon.rb +26 -0
- data/lib/ptj/parser/fileparser/passhashonly.rb +26 -0
- data/lib/ptj/parser/fileparser/passonly.rb +26 -0
- data/lib/ptj/parser/fileparser/passthreecolons.rb +26 -0
- data/ptj.gemspec +120 -0
- data/scripts/analyze.rb +129 -0
- data/scripts/generate_wordlist.rb +121 -0
- data/scripts/import.rb +111 -0
- data/scripts/ptj_libpath.rb +2 -0
- data/spec/.helper.rb.swp +0 -0
- data/spec/.test_ptj.rb.swp +0 -0
- data/spec/model/password_spec.rb +46 -0
- data/spec/model/shared_behaviors.rb +23 -0
- data/spec/model/tag_spec.rb +27 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/spec_ptj.rb +16 -0
- data/tasks/db.rake +68 -0
- data/tasks/irb.rake +8 -0
- metadata +263 -0
data/lib/ptj/ext.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ptj/ext/datamapper_collection'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
|
5
|
+
class Collection < LazyArray
|
6
|
+
|
7
|
+
def get_value(entry)
|
8
|
+
returned_array = []
|
9
|
+
self.each do |item|
|
10
|
+
meth = item.method(entry)
|
11
|
+
returned_array << meth.call()
|
12
|
+
end
|
13
|
+
returned_array
|
14
|
+
end
|
15
|
+
|
16
|
+
def analyze_and_sort
|
17
|
+
b = Hash.new(0)
|
18
|
+
self.each do |item|
|
19
|
+
meth = item.method(entry)
|
20
|
+
b[meth.call()] += 1
|
21
|
+
end
|
22
|
+
b = b.sort_by { |k,v| -1*v }
|
23
|
+
b
|
24
|
+
end
|
25
|
+
|
26
|
+
def analyze
|
27
|
+
h = Hash.new(0)
|
28
|
+
self.each { | v | h.store(v, h[v]+1) }
|
29
|
+
h
|
30
|
+
end
|
31
|
+
|
32
|
+
def sort_by_occurance(entry)
|
33
|
+
returned_array = []
|
34
|
+
sorted_array = self.analyze_and_sort(entry)
|
35
|
+
sorted_array.each do |smaller_array|
|
36
|
+
returned_array << smaller_array[0]
|
37
|
+
end
|
38
|
+
returned_array
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Array
|
45
|
+
def analyze
|
46
|
+
h = Hash.new(0)
|
47
|
+
self.each { | v | h.store(v, h[v]+1) }
|
48
|
+
h
|
49
|
+
end
|
50
|
+
|
51
|
+
def analyze_and_sort
|
52
|
+
b = Hash.new(0)
|
53
|
+
self.each { | v | b.store(v, b[v]+1) }
|
54
|
+
b = b.sort_by { |k,v| -1*v }
|
55
|
+
b
|
56
|
+
end
|
57
|
+
|
58
|
+
def analyze_and_sort_key
|
59
|
+
b = Hash.new(0)
|
60
|
+
self.each { | v | b.store(v, b[v]+1) }
|
61
|
+
b = b.sort_by { |k,v| k }
|
62
|
+
b
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
module Kernel
|
68
|
+
def Boolean(string)
|
69
|
+
return true if string== true || string =~ (/(true|t|yes|y|1)$/i)
|
70
|
+
return false if string== false || string.nil? || string =~ (/(false|f|no|n|0)$/i)
|
71
|
+
raise ArgumentError.new("invalid value for Boolean: \"#{string}\"")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
data/lib/ptj/model.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types'
|
3
|
+
require 'dm-migrations'
|
4
|
+
require 'dm-transactions'
|
5
|
+
require 'dm-validations'
|
6
|
+
require 'dm-serializer'
|
7
|
+
require 'dm-timestamps'
|
8
|
+
require 'dm-aggregates'
|
9
|
+
|
10
|
+
|
11
|
+
require 'ptj/environment'
|
12
|
+
|
13
|
+
module PTJ
|
14
|
+
|
15
|
+
module Model
|
16
|
+
module FixtureTable
|
17
|
+
def fixture_table?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
require 'ptj/model/password'
|
24
|
+
require 'ptj/model/tag'
|
25
|
+
|
26
|
+
# Sets up the model using with the currently configured db_conn
|
27
|
+
# configuration.
|
28
|
+
def self.setup!
|
29
|
+
DataMapper::Logger.new($stdout, :debug) if Env::CONFIG[Env::KEY_DEBUG]
|
30
|
+
DataMapper.setup(:default, Env::CONFIG[Env::KEY_DB_CONN])
|
31
|
+
DataMapper.finalize
|
32
|
+
@setup = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return True,False
|
36
|
+
# Indicates whether the the model has been set up yet with the
|
37
|
+
# setup! method.
|
38
|
+
def self.setup?
|
39
|
+
@setup == true
|
40
|
+
end
|
41
|
+
|
42
|
+
# Updates the model schema in the current database.
|
43
|
+
#
|
44
|
+
# @return Object
|
45
|
+
# Returns the return value from DataMapper.auto_upgrade!
|
46
|
+
def self.migrate_all!
|
47
|
+
setup! unless setup?
|
48
|
+
# use a non-destructive schema migration across the whole model
|
49
|
+
ret=DataMapper.auto_upgrade!
|
50
|
+
@migrated = true
|
51
|
+
return ret
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return True,False
|
55
|
+
# Indicates whether the current model has been migrated
|
56
|
+
# (via auto_upgrade).
|
57
|
+
def self.migrated?
|
58
|
+
@migrated == true
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
module PTJ
|
3
|
+
|
4
|
+
class Password
|
5
|
+
include DataMapper::Resource
|
6
|
+
include Model::FixtureTable
|
7
|
+
|
8
|
+
# id value for every entry
|
9
|
+
property :id, Serial
|
10
|
+
|
11
|
+
# password
|
12
|
+
property :password, String, :required => true
|
13
|
+
|
14
|
+
# hash of password
|
15
|
+
property :pw_hash, String
|
16
|
+
|
17
|
+
# time this was added to database
|
18
|
+
property :created_at, DateTime, :writer => :private
|
19
|
+
|
20
|
+
# upper-case letters in password
|
21
|
+
property :upper, Boolean,
|
22
|
+
:default => lambda{|this,p| self.classify_passwords(this.password)[:upper] }
|
23
|
+
|
24
|
+
# lower-case letters in password
|
25
|
+
property :lower, Boolean,
|
26
|
+
:default => lambda{|this,p| self.classify_passwords(this.password)[:lower] }
|
27
|
+
|
28
|
+
# numbers in password
|
29
|
+
property :number, Boolean,
|
30
|
+
:default => lambda{|this,p| self.classify_passwords(this.password)[:number] }
|
31
|
+
|
32
|
+
# special characters in password
|
33
|
+
property :special, Boolean,
|
34
|
+
:default => lambda{|this,p| self.classify_passwords(this.password)[:special] }
|
35
|
+
|
36
|
+
# length of the password
|
37
|
+
property :size, Integer,
|
38
|
+
:default => lambda{|this,p| this.password.size }
|
39
|
+
|
40
|
+
# Tags associated with a sample
|
41
|
+
has n, :tags, :through => Resource
|
42
|
+
|
43
|
+
# Classify an individual password based on the levels of complexities
|
44
|
+
# present.
|
45
|
+
#
|
46
|
+
# @param pass
|
47
|
+
# Password to classify.
|
48
|
+
#
|
49
|
+
# @return Hash
|
50
|
+
# :lower => value, :upper => value, :special => value, :number => value
|
51
|
+
def self.classify_passwords(pass)
|
52
|
+
pass = pass.to_s
|
53
|
+
lower = false
|
54
|
+
upper = false
|
55
|
+
special = false
|
56
|
+
number = false
|
57
|
+
|
58
|
+
case pass
|
59
|
+
when /^[a-z]+$/
|
60
|
+
lower = true
|
61
|
+
when /^[^a-zA-Z0-9]+$/
|
62
|
+
special = true
|
63
|
+
when /^[A-Z]+$/
|
64
|
+
upper = true
|
65
|
+
when /^[0-9]+$/
|
66
|
+
number = true
|
67
|
+
when /^([a-zA-Z]*([a-z]+[A-Z]+|[A-Z]+[a-z]+)[a-zA-Z]*)$/
|
68
|
+
lower = upper = true
|
69
|
+
when /^([a-z0-9]*([a-z]+[0-9]+|[0-9]+[a-z]+)[a-z0-9]*)$/
|
70
|
+
lower = number = true
|
71
|
+
when /^(([a-z]|[^a-zA-Z0-9])*([a-z]+[^a-zA-Z0-9]+|[^a-zA-Z0-9]+[a-z]+)([a-z]|[^a-zA-Z0-9])*)$/
|
72
|
+
lower = special = true
|
73
|
+
when /^([0-9A-Z]*([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*)$/
|
74
|
+
upper = number = true
|
75
|
+
when /^(([A-Z]|[^a-zA-Z0-9])*([A-Z]+[^a-zA-Z0-9]+|[^a-zA-Z0-9]+[A-Z]+)([A-Z]|[^a-zA-Z0-9])*)$/
|
76
|
+
upper = special = true
|
77
|
+
when /^(([0-9]|[^a-zA-Z0-9])*([0-9]+[^a-zA-Z0-9]+|[^a-zA-Z0-9]+[0-9]+)([0-9]|[^a-zA-Z0-9])*)$/
|
78
|
+
number = special = true
|
79
|
+
when /^([a-zA-Z0-9]*([a-z]+[A-Z]+[0-9]+|[a-z]+[0-9]+[A-Z]+|[A-Z]+[a-z]+[0-9]+|[A-Z]+[0-9]+[a-z]+|[0-9]+[A-Z]+[a-z]+|[0-9]+[a-z]+[A-Z]+)+[a-zA-Z0-9]*)$/
|
80
|
+
lower = upper = number = true
|
81
|
+
when /^(([^a-zA-Z0-9]|[A-Z0-9])*([^a-zA-Z0-9]+[A-Z]+[0-9]+|[^a-zA-Z0-9]+[0-9]+[A-Z]+|[A-Z]+[^a-zA-Z0-9]+[0-9]+|[A-Z]+[0-9]+[^a-zA-Z0-9]+|[0-9]+[A-Z]+[^a-zA-Z0-9]+|[0-9]+[^a-zA-Z0-9]+[A-Z]+)+([^a-zA-Z0-9]|[A-Z0-9])*)$/
|
82
|
+
upper = number = special = true
|
83
|
+
when /^(([^a-zA-Z0-9]|[a-z0-9])*([^a-zA-Z0-9]+[a-z]+[0-9]+|[^a-zA-Z0-9]+[0-9]+[a-z]+|[a-z]+[^a-zA-Z0-9]+[0-9]+|[a-z]+[0-9]+[^a-zA-Z0-9]+|[0-9]+[a-z]+[^a-zA-Z0-9]+|[0-9]+[^a-zA-Z0-9]+[a-z]+)+([^a-zA-Z0-9]|[a-z0-9])*)$/
|
84
|
+
lower = number = special = true
|
85
|
+
when /^(([^a-zA-Z0-9]|[a-zA-Z])*([^a-zA-Z0-9]+[a-z]+[A-Z]+|[^a-zA-Z0-9]+[A-Z]+[a-z]+|[a-z]+[^a-zA-Z0-9]+[A-Z]+|[a-z]+[A-Z]+[^a-zA-Z0-9]+|[A-Z]+[a-z]+[^a-zA-Z0-9]+|[A-Z]+[^a-zA-Z0-9]+[a-z]+)+([^a-zA-Z0-9]|[a-zA-Z])*)$/
|
86
|
+
lower = upper = special = true
|
87
|
+
else
|
88
|
+
lower = number = special = upper = true unless pass == ""
|
89
|
+
end
|
90
|
+
|
91
|
+
return {:lower => lower, :upper => upper, :special => special, :number => number}
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add a single password/hash to the database.
|
95
|
+
#
|
96
|
+
# @param mypass
|
97
|
+
# Password to add.
|
98
|
+
#
|
99
|
+
# @param myhash
|
100
|
+
# Password hash to add.
|
101
|
+
#
|
102
|
+
# @return DataMapper::Password
|
103
|
+
def self.add_single(mypass, myhash = "")
|
104
|
+
begin
|
105
|
+
return if mypass.to_s.empty?
|
106
|
+
pass = Password.create!(:password => mypass, :pw_hash => myhash)
|
107
|
+
pass.save!
|
108
|
+
pass
|
109
|
+
rescue
|
110
|
+
return
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PTJ
|
2
|
+
|
3
|
+
class Tag
|
4
|
+
include DataMapper::Resource
|
5
|
+
include Model::FixtureTable
|
6
|
+
|
7
|
+
# A textual tag name
|
8
|
+
property :tag, String, :key => true
|
9
|
+
|
10
|
+
# An optional description of the tag.
|
11
|
+
property :description, Text
|
12
|
+
|
13
|
+
property :created_at, DateTime, :writer => :private
|
14
|
+
property :updated_at, DateTime, :writer => :private
|
15
|
+
|
16
|
+
has n, :passwords, :through => Resource
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module PTJ
|
5
|
+
class Task
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
property :id, Serial
|
9
|
+
property :description, Text, :required => true
|
10
|
+
property :is_done, Boolean
|
11
|
+
|
12
|
+
def url
|
13
|
+
"/tasks/#{self.id}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_json(*a)
|
17
|
+
{
|
18
|
+
'guid' => self.url,
|
19
|
+
'description' => self.description,
|
20
|
+
'isDone' => self.is_done
|
21
|
+
}.to_json(*a)
|
22
|
+
end
|
23
|
+
|
24
|
+
REQUIRED = [:description, :is_done]
|
25
|
+
|
26
|
+
def self.parse_json(body)
|
27
|
+
json = JSON.parse(body)
|
28
|
+
ret = { :description => json['description'], :is_done => json['isDone'] }
|
29
|
+
return nil if REQUIRED.find { |r| ret[r].nil? }
|
30
|
+
|
31
|
+
ret
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/lib/ptj/parser.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ptj/parser/fileparser'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module PTJ
|
2
|
+
module Parser
|
3
|
+
class FileParser
|
4
|
+
|
5
|
+
# Parse a file line-by-line and return the necessary results.
|
6
|
+
#
|
7
|
+
# @param line
|
8
|
+
# Individual line of the file.
|
9
|
+
#
|
10
|
+
# @return Hash
|
11
|
+
# :mypass => value, :myhash => value, :count => value (optional)
|
12
|
+
def parse_line(line)
|
13
|
+
raise(NotImplementedError, "This is an abstract implementation, you must override parse_line")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'ptj/parser/fileparser/passhashonly'
|
21
|
+
require 'ptj/parser/fileparser/passonly'
|
22
|
+
require 'ptj/parser/fileparser/hashpassonlycolon'
|
23
|
+
require 'ptj/parser/fileparser/countpassonly'
|
24
|
+
require 'ptj/parser/fileparser/passthreecolons'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PTJ
|
2
|
+
module Parser
|
3
|
+
# FileParser class which allows you to parse a file line by line.
|
4
|
+
#
|
5
|
+
class CountPassOnly < FileParser
|
6
|
+
|
7
|
+
# Expecting the following format:
|
8
|
+
# pass, hash
|
9
|
+
# pass, hash
|
10
|
+
# pass, hash
|
11
|
+
#
|
12
|
+
# @param line
|
13
|
+
# Individual line from a text file
|
14
|
+
#
|
15
|
+
# @return Hash Password, Password Hash, Count
|
16
|
+
def parse_line(line)
|
17
|
+
if line =~ /^\s*(\d+)\s*(\S+)\s*$/
|
18
|
+
count = $~[1]
|
19
|
+
pass = $~[2]
|
20
|
+
hash = nil
|
21
|
+
end
|
22
|
+
{:mypass => pass, :myhash => hash, :count => count}
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module PTJ
|
2
|
+
module Parser
|
3
|
+
# FileParser class which allows you to parse a file line by line.
|
4
|
+
#
|
5
|
+
class HashPassOnlyColon < FileParser
|
6
|
+
|
7
|
+
# Expecting the following format:
|
8
|
+
# hash:pass
|
9
|
+
# hash:pass
|
10
|
+
# hash:pass
|
11
|
+
#
|
12
|
+
# @param line
|
13
|
+
# Individual line from a text file
|
14
|
+
#
|
15
|
+
# @return Hash Password, Password Hash
|
16
|
+
def parse_line(line)
|
17
|
+
if line =~ /^(\S+):(\S+)/
|
18
|
+
pass = $~[2]
|
19
|
+
hash = $~[1]
|
20
|
+
end
|
21
|
+
{:mypass => pass, :myhash => hash}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module PTJ
|
2
|
+
module Parser
|
3
|
+
# FileParser class which allows you to parse a file line by line.
|
4
|
+
#
|
5
|
+
class PassHashOnly < FileParser
|
6
|
+
|
7
|
+
# Expecting the following format:
|
8
|
+
# pass, hash
|
9
|
+
# pass, hash
|
10
|
+
# pass, hash
|
11
|
+
#
|
12
|
+
# @param line
|
13
|
+
# Individual line from a text file
|
14
|
+
#
|
15
|
+
# @return Hash Password, Password Hash
|
16
|
+
def parse_line(line)
|
17
|
+
if line =~ /^(\S+),\s(\S+)/
|
18
|
+
pass = $~[1]
|
19
|
+
hash = $~[2]
|
20
|
+
end
|
21
|
+
{:mypass => pass, :myhash => hash}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module PTJ
|
2
|
+
module Parser
|
3
|
+
# FileParser class which allows you to parse a file line by line.
|
4
|
+
#
|
5
|
+
class PassOnly < FileParser
|
6
|
+
|
7
|
+
# Expecting the following format:
|
8
|
+
# pass
|
9
|
+
# pass
|
10
|
+
# pass
|
11
|
+
#
|
12
|
+
# @param line
|
13
|
+
# Individual line from a text file
|
14
|
+
#
|
15
|
+
# @return Hash Password, Password Hash
|
16
|
+
def parse_line(line)
|
17
|
+
if line =~ /^\s*(\S+)\s*$/
|
18
|
+
pass = $~[1]
|
19
|
+
hash = nil
|
20
|
+
end
|
21
|
+
{:mypass => pass, :myhash => hash}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|