ya 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +3 -0
- data/LICENSE +20 -0
- data/README.rdoc +8 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/lib/ya.rb +13 -0
- data/lib/ya/digest.rb +26 -0
- data/lib/ya/directory.rb +40 -0
- data/test/helper.rb +12 -0
- data/test/test_ya.rb +105 -0
- data/ya.gemspec +56 -0
- metadata +77 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Carsten Nielsen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = 'ya'
|
8
|
+
gem.summary = %Q{Ya is an authentication system uses a YAML file to store credentials}
|
9
|
+
gem.description = %Q{Ya is a simple authentication system which uses a YAML flat file to store directory info.}
|
10
|
+
gem.email = 'heycarsten@gmail.com'
|
11
|
+
gem.homepage = 'http://github.com/heycarsten/ya'
|
12
|
+
gem.author = 'Carsten Nielsen'
|
13
|
+
gem.add_development_dependency 'thoughtbot-shoulda', '>= 0'
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/testtask'
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
22
|
+
test.libs << 'lib' << 'test'
|
23
|
+
test.pattern = 'test/**/test_*.rb'
|
24
|
+
test.verbose = true
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort 'RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :test => :check_dependencies
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "ya #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/ya.rb
ADDED
data/lib/ya/digest.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ya
|
2
|
+
module Digest
|
3
|
+
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
RANDOM_SEED = 9999999999999999
|
7
|
+
|
8
|
+
def salt_password(salt, password)
|
9
|
+
raise ArgumentError, 'salt can not be nil' unless salt
|
10
|
+
::Digest::SHA1.hexdigest("#{salt}---#{password}")
|
11
|
+
end
|
12
|
+
|
13
|
+
def random_hash
|
14
|
+
::Digest::SHA1.hexdigest("#{Time.now}-#{rand RANDOM_SEED}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate(login, password, attrs = {})
|
18
|
+
salt = random_hash
|
19
|
+
hash = salt_password(salt, password)
|
20
|
+
{ :"#{login}" => { :salt => salt, :hash => hash }.merge(attrs) }
|
21
|
+
end
|
22
|
+
|
23
|
+
module_function :salt_password, :random_hash, :generate
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/ya/directory.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Ya
|
2
|
+
class Directory
|
3
|
+
|
4
|
+
def initialize(access_file)
|
5
|
+
@access_file = access_file
|
6
|
+
FileUtils.touch(@access_file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def lookup(login)
|
10
|
+
load[login.to_sym]
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticate(login, password)
|
14
|
+
record = lookup(login)
|
15
|
+
return nil unless record
|
16
|
+
challenge = Digest.salt_password(record[:salt], password)
|
17
|
+
challenge == record[:hash] ? { login => record } : false
|
18
|
+
end
|
19
|
+
|
20
|
+
def add(login, password, attrs = {})
|
21
|
+
dump(load.merge(Digest.generate(login, password, attrs)))
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(login)
|
25
|
+
dictionary = load
|
26
|
+
dictionary.delete(login.to_sym) ? dump(dictionary) : false
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def load
|
32
|
+
YAML.load_file(@access_file) || {}
|
33
|
+
end
|
34
|
+
|
35
|
+
def dump(directory)
|
36
|
+
File.open(@access_file, 'w') { |f| f.puts(directory.to_yaml) }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/test/helper.rb
ADDED
data/test/test_ya.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestYa < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'Ya' do
|
6
|
+
should 'delegate .open to Directory.new' do
|
7
|
+
assert_respond_to Ya, :open
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'Ya::Directory' do
|
12
|
+
setup { @directory = Ya.open('test.yml') }
|
13
|
+
teardown { FileUtils.rm('test.yml') }
|
14
|
+
|
15
|
+
context '#add' do
|
16
|
+
setup { @directory.add('somebody', 'password', :meta => 'data') }
|
17
|
+
|
18
|
+
should 'add the record' do
|
19
|
+
assert_instance_of Hash, @directory.lookup('somebody')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'Ya::Directory (for a pre-existing directory)' do
|
25
|
+
setup do
|
26
|
+
@directory = Ya.open('test.yml')
|
27
|
+
@directory.add('heycarsten', 'password', :meta => 'data')
|
28
|
+
@directory.add('usermate', 'password', :lucky => 7)
|
29
|
+
@directory.add('somebody', 'password')
|
30
|
+
end
|
31
|
+
|
32
|
+
teardown do
|
33
|
+
FileUtils.rm('test.yml')
|
34
|
+
end
|
35
|
+
|
36
|
+
context '#remove (for a record that exists)' do
|
37
|
+
setup { @directory.remove('heycarsten') }
|
38
|
+
|
39
|
+
should 'remove the record' do
|
40
|
+
assert_nil @directory.lookup('heycarsten')
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'not remove other records' do
|
44
|
+
assert_instance_of Hash, @directory.lookup('usermate')
|
45
|
+
assert_instance_of Hash, @directory.lookup('somebody')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context '#remove (for a record that does not exist)' do
|
50
|
+
setup { @directory.remove('nobody') }
|
51
|
+
|
52
|
+
should 'change nothing' do
|
53
|
+
assert_instance_of Hash, @directory.lookup('heycarsten')
|
54
|
+
assert_instance_of Hash, @directory.lookup('usermate')
|
55
|
+
assert_instance_of Hash, @directory.lookup('somebody')
|
56
|
+
assert_nil @directory.lookup('nobody')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context '#authenticate' do
|
61
|
+
should 'return nil' do
|
62
|
+
assert_nil @directory.authenticate('username', 'password')
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'authenticate if proper credentials are passed' do
|
66
|
+
assert_instance_of Hash, @directory.authenticate('somebody', 'password')
|
67
|
+
end
|
68
|
+
|
69
|
+
should 'return false for authentication with invalid credentails' do
|
70
|
+
assert_equal false, @directory.authenticate('somebody', 'fails')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'Ya::Digest' do
|
76
|
+
context '.generate' do
|
77
|
+
should 'return a hash representing a new record' do
|
78
|
+
record = Ya::Digest.generate('username', 'password', :extra => 'stuff')
|
79
|
+
assert_equal 40, record[:username][:salt].length
|
80
|
+
assert_equal 40, record[:username][:hash].length
|
81
|
+
assert_equal 'stuff', record[:username][:extra]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context '.random_hash' do
|
86
|
+
should 'return a random hash' do
|
87
|
+
assert_equal 40, Ya::Digest.random_hash.length
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context '.salt_password' do
|
92
|
+
should 'return a hash of the password and salt' do
|
93
|
+
assert_equal 'd0e40f494e57fdcc6f30ef5be663498883a7eefa',
|
94
|
+
Ya::Digest.salt_password('salt', 'password')
|
95
|
+
end
|
96
|
+
|
97
|
+
should 'fail if nil is passed as a salt' do
|
98
|
+
assert_raises ArgumentError do
|
99
|
+
Ya::Digest.salt_password(nil, 'password')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
data/ya.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ya}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Carsten Nielsen"]
|
12
|
+
s.date = %q{2009-11-23}
|
13
|
+
s.description = %q{Ya is a simple authentication system which uses a YAML flat file to store directory info.}
|
14
|
+
s.email = %q{heycarsten@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/ya.rb",
|
27
|
+
"lib/ya/digest.rb",
|
28
|
+
"lib/ya/directory.rb",
|
29
|
+
"test/helper.rb",
|
30
|
+
"test/test_ya.rb",
|
31
|
+
"ya.gemspec"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/heycarsten/ya}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Ya is an authentication system uses a YAML file to store credentials}
|
38
|
+
s.test_files = [
|
39
|
+
"test/helper.rb",
|
40
|
+
"test/test_ya.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
49
|
+
else
|
50
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
51
|
+
end
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ya
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carsten Nielsen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-23 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Ya is a simple authentication system which uses a YAML flat file to store directory info.
|
26
|
+
email: heycarsten@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- lib/ya.rb
|
42
|
+
- lib/ya/digest.rb
|
43
|
+
- lib/ya/directory.rb
|
44
|
+
- test/helper.rb
|
45
|
+
- test/test_ya.rb
|
46
|
+
- ya.gemspec
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/heycarsten/ya
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --charset=UTF-8
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.5
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Ya is an authentication system uses a YAML file to store credentials
|
75
|
+
test_files:
|
76
|
+
- test/helper.rb
|
77
|
+
- test/test_ya.rb
|