ghaki-account 2011.11.29.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README +23 -0
- data/VERSION +1 -0
- data/lib/ghaki/account/base.rb +78 -0
- data/lib/ghaki/account/database.rb +66 -0
- data/lib/ghaki/account/db_connect.rb +45 -0
- data/lib/ghaki/account/db_driver.rb +22 -0
- data/lib/ghaki/account/db_name.rb +22 -0
- data/lib/ghaki/account/db_port.rb +22 -0
- data/lib/ghaki/account/domain_address.rb +39 -0
- data/lib/ghaki/account/email_address.rb +39 -0
- data/lib/ghaki/account/errors.rb +10 -0
- data/lib/ghaki/account/hostname.rb +95 -0
- data/lib/ghaki/account/password.rb +101 -0
- data/lib/ghaki/account/syn_opts.rb +42 -0
- data/lib/ghaki/account/userdomain.rb +88 -0
- data/lib/ghaki/account/username.rb +93 -0
- data/lib/ghaki/account/windos.rb +58 -0
- data/spec/ghaki/account/base_spec.rb +121 -0
- data/spec/ghaki/account/database_spec.rb +96 -0
- data/spec/ghaki/account/db_connect_spec.rb +79 -0
- data/spec/ghaki/account/db_driver_spec.rb +44 -0
- data/spec/ghaki/account/db_name_spec.rb +43 -0
- data/spec/ghaki/account/db_port_spec.rb +49 -0
- data/spec/ghaki/account/domain_address_spec.rb +30 -0
- data/spec/ghaki/account/email_address_spec.rb +30 -0
- data/spec/ghaki/account/hostname_spec.rb +110 -0
- data/spec/ghaki/account/password_spec.rb +155 -0
- data/spec/ghaki/account/syn_opts_helper.rb +90 -0
- data/spec/ghaki/account/syn_opts_spec.rb +36 -0
- data/spec/ghaki/account/userdomain_spec.rb +69 -0
- data/spec/ghaki/account/username_spec.rb +67 -0
- data/spec/ghaki/account/windos_spec.rb +107 -0
- data/spec/spec_helper.rb +6 -0
- metadata +139 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
############################################################################
|
2
|
+
require 'highline'
|
3
|
+
require 'ghaki/account/errors'
|
4
|
+
require 'ghaki/account/syn_opts'
|
5
|
+
|
6
|
+
############################################################################
|
7
|
+
module Ghaki #:nodoc:
|
8
|
+
module Account #:nodoc:
|
9
|
+
|
10
|
+
module Password
|
11
|
+
|
12
|
+
######################################################################
|
13
|
+
# SYNONYM OPTIONS
|
14
|
+
######################################################################
|
15
|
+
extend SynOpts
|
16
|
+
attr_syn_opts :password, :passwords
|
17
|
+
|
18
|
+
# overrides autogenerated
|
19
|
+
def opt_password opts
|
20
|
+
val = Password.parse_opts( opts )
|
21
|
+
self.passwords = val
|
22
|
+
end
|
23
|
+
|
24
|
+
######################################################################
|
25
|
+
# CONSTANTS
|
26
|
+
######################################################################
|
27
|
+
ASK_PASSWORD_RETRY_MAX = 3
|
28
|
+
|
29
|
+
######################################################################
|
30
|
+
# OBJECT METHODS
|
31
|
+
######################################################################
|
32
|
+
|
33
|
+
def password
|
34
|
+
@cur_password ||= _try_passwords.first
|
35
|
+
end
|
36
|
+
def passwords
|
37
|
+
@all_passwords ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
def passwords= pass
|
41
|
+
@cur_passwords = nil
|
42
|
+
@all_passwords = if pass.nil? then [] else [pass].flatten end
|
43
|
+
end
|
44
|
+
alias_method :password=, :passwords=
|
45
|
+
|
46
|
+
def reset_passwords
|
47
|
+
@try_passwords = nil
|
48
|
+
@bad_passwords = nil
|
49
|
+
@cur_password = nil
|
50
|
+
end
|
51
|
+
def fail_password
|
52
|
+
_bad_passwords.push _try_passwords.shift unless _try_passwords.empty?
|
53
|
+
end
|
54
|
+
def retry_password?
|
55
|
+
!_try_passwords.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
def valid_password?
|
59
|
+
!passwords.empty?
|
60
|
+
end
|
61
|
+
|
62
|
+
def failed_passwords?
|
63
|
+
!_bad_passwords.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
def ask_password opts={}
|
67
|
+
f_ques,r_ques = _password_prompt( opts ), nil
|
68
|
+
(1..(opts[:retry_max] || ASK_PASSWORD_RETRY_MAX)).each do
|
69
|
+
self.password = HighLine.new.ask( r_ques || f_ques ) do |q|
|
70
|
+
q.echo = '*'
|
71
|
+
end
|
72
|
+
return self.password if valid_password?
|
73
|
+
r_ques ||= '* TRY AGAIN * ' + f_ques
|
74
|
+
end
|
75
|
+
raise InvalidPasswordError, 'Invalid Password Specified'
|
76
|
+
end
|
77
|
+
|
78
|
+
protected
|
79
|
+
|
80
|
+
def _try_passwords
|
81
|
+
@try_passwords ||= self.passwords.clone
|
82
|
+
end
|
83
|
+
def _bad_passwords
|
84
|
+
@bad_passwords ||= []
|
85
|
+
end
|
86
|
+
|
87
|
+
def _password_prompt opts
|
88
|
+
prompt = 'Password: '
|
89
|
+
case opts[:prompt]
|
90
|
+
when nil, :default
|
91
|
+
when :auto
|
92
|
+
unless @username.nil? and @hostname.nil?
|
93
|
+
prompt = '(' + (@username || '*') +
|
94
|
+
'@' + (@hostname || '*') +
|
95
|
+
') ' + prompt
|
96
|
+
end
|
97
|
+
end
|
98
|
+
prompt
|
99
|
+
end
|
100
|
+
|
101
|
+
end end end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
############################################################################
|
2
|
+
module Ghaki
|
3
|
+
module Account
|
4
|
+
module SynOpts
|
5
|
+
|
6
|
+
#---------------------------------------------------------------------
|
7
|
+
def attr_syn_opts token, *syn_list
|
8
|
+
klass = self.to_s.split('::').last
|
9
|
+
konst = klass.upcase
|
10
|
+
module_eval <<-"END"
|
11
|
+
|
12
|
+
#{konst}_LIST = syn_list
|
13
|
+
|
14
|
+
def #{klass}.parse_opts opts
|
15
|
+
return opts[ :#{token} ] if opts.has_key?( :#{token} )
|
16
|
+
#{konst}_LIST.each do |name|
|
17
|
+
return opts[name] if opts.has_key?(name)
|
18
|
+
end
|
19
|
+
return opts[:account].#{token} if opts.has_key?(:account)
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def #{klass}.purge_opts opts
|
24
|
+
opts.delete( :#{token} )
|
25
|
+
#{konst}_LIST.each do |name|
|
26
|
+
opts.delete(name)
|
27
|
+
end
|
28
|
+
opts
|
29
|
+
end
|
30
|
+
|
31
|
+
def opt_#{token} opts
|
32
|
+
val = #{klass}.parse_opts( opts )
|
33
|
+
@#{token} = val unless val.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
END
|
37
|
+
end
|
38
|
+
|
39
|
+
end # helper
|
40
|
+
end # namespace
|
41
|
+
end # package
|
42
|
+
############################################################################
|
@@ -0,0 +1,88 @@
|
|
1
|
+
############################################################################
|
2
|
+
require 'highline'
|
3
|
+
require 'ghaki/account/errors'
|
4
|
+
require 'ghaki/account/syn_opts'
|
5
|
+
|
6
|
+
############################################################################
|
7
|
+
module Ghaki
|
8
|
+
module Account
|
9
|
+
module UserDomain
|
10
|
+
|
11
|
+
######################################################################
|
12
|
+
extend SynOpts
|
13
|
+
attr_syn_opts :userdomain, :user_domain
|
14
|
+
|
15
|
+
######################################################################
|
16
|
+
# CONSTANTS
|
17
|
+
######################################################################
|
18
|
+
USERDOMAIN_RETRY_MAX = 3
|
19
|
+
|
20
|
+
######################################################################
|
21
|
+
# CLASS METHODS
|
22
|
+
######################################################################
|
23
|
+
|
24
|
+
#---------------------------------------------------------------------
|
25
|
+
def UserDomain.get_env
|
26
|
+
ENV['USERDOMAIN']
|
27
|
+
end
|
28
|
+
|
29
|
+
######################################################################
|
30
|
+
# OBJECT METHODS
|
31
|
+
######################################################################
|
32
|
+
attr_reader :userdomain
|
33
|
+
|
34
|
+
#---------------------------------------------------------------------
|
35
|
+
def userdomain= val
|
36
|
+
case val
|
37
|
+
when :env
|
38
|
+
@userdomain = UserDomain.get_env
|
39
|
+
when String
|
40
|
+
@userdomain = val.strip
|
41
|
+
else
|
42
|
+
@userdomain = val
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#---------------------------------------------------------------------
|
47
|
+
def valid_userdomain?
|
48
|
+
return false if @userdomain.nil?
|
49
|
+
return false if @userdomain.empty?
|
50
|
+
return false unless @userdomain =~ %r{\A\w+\z}o
|
51
|
+
return true
|
52
|
+
end
|
53
|
+
|
54
|
+
#---------------------------------------------------------------------
|
55
|
+
def ask_userdomain opts={}
|
56
|
+
o_prompt,r_prompt = _userdomain_prompt(opts), nil
|
57
|
+
defval = opts[:default] || @userdomain
|
58
|
+
defval = UserDomain.get_env if defval == :env
|
59
|
+
(1 .. (opts[:retry_max] || USERDOMAIN_RETRY_MAX) ).each do
|
60
|
+
self.userdomain = HighLine.new.ask( r_prompt||o_prompt ) do |q|
|
61
|
+
q.echo = true
|
62
|
+
q.default = defval unless defval.nil?
|
63
|
+
end
|
64
|
+
return @userdomain if valid_userdomain?
|
65
|
+
r_prompt ||= '* TRY AGAIN * ' + o_prompt
|
66
|
+
end
|
67
|
+
raise InvalidUserDomainError, "Invalid User Domain: #{@userdomain}"
|
68
|
+
end
|
69
|
+
|
70
|
+
######################################################################
|
71
|
+
protected
|
72
|
+
######################################################################
|
73
|
+
|
74
|
+
#---------------------------------------------------------------------
|
75
|
+
def _userdomain_prompt opts
|
76
|
+
prompt = 'User Domain: '
|
77
|
+
case opts[:prompt]
|
78
|
+
when nil, :default, :auto
|
79
|
+
else
|
80
|
+
prompt = opts[:prompt]
|
81
|
+
end
|
82
|
+
prompt
|
83
|
+
end
|
84
|
+
|
85
|
+
end # class
|
86
|
+
end # namespace
|
87
|
+
end # package
|
88
|
+
############################################################################
|
@@ -0,0 +1,93 @@
|
|
1
|
+
############################################################################
|
2
|
+
require 'etc'
|
3
|
+
require 'highline'
|
4
|
+
require 'ghaki/account/errors'
|
5
|
+
require 'ghaki/account/syn_opts'
|
6
|
+
|
7
|
+
############################################################################
|
8
|
+
module Ghaki
|
9
|
+
module Account
|
10
|
+
module Username
|
11
|
+
|
12
|
+
######################################################################
|
13
|
+
extend SynOpts
|
14
|
+
attr_syn_opts :username, :user_name, :user
|
15
|
+
|
16
|
+
######################################################################
|
17
|
+
# CONSTANTS
|
18
|
+
######################################################################
|
19
|
+
USERNAME_RETRY_MAX = 3
|
20
|
+
|
21
|
+
######################################################################
|
22
|
+
# CLASS METHODS
|
23
|
+
######################################################################
|
24
|
+
|
25
|
+
#---------------------------------------------------------------------
|
26
|
+
def Username.get_env
|
27
|
+
Etc.getlogin
|
28
|
+
end
|
29
|
+
|
30
|
+
######################################################################
|
31
|
+
# OBJECT METHODS
|
32
|
+
######################################################################
|
33
|
+
attr_reader :username
|
34
|
+
|
35
|
+
#---------------------------------------------------------------------
|
36
|
+
def username= val
|
37
|
+
case val
|
38
|
+
when String
|
39
|
+
@username = val.strip
|
40
|
+
when :env
|
41
|
+
@username = Username.get_env
|
42
|
+
else
|
43
|
+
@username = val
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#---------------------------------------------------------------------
|
48
|
+
def valid_username?
|
49
|
+
return false if @username.nil?
|
50
|
+
return false if @username.empty?
|
51
|
+
return false unless @username =~ %r{\A\S+\z}o
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
#---------------------------------------------------------------------
|
56
|
+
def ask_username opts={}
|
57
|
+
f_ques,r_ques = _username_prompt(opts), nil
|
58
|
+
defval = opts[:default] || @username
|
59
|
+
defval = Username.get_env if defval == :env
|
60
|
+
(1 .. (opts[:retry_max] || USERNAME_RETRY_MAX) ).each do
|
61
|
+
@username = HighLine.new.ask( r_ques || f_ques ) do |q|
|
62
|
+
q.echo = true
|
63
|
+
q.default = defval unless defval.nil?
|
64
|
+
end
|
65
|
+
return @username if valid_username?
|
66
|
+
r_ques ||= '* TRY AGAIN * ' + f_ques
|
67
|
+
end
|
68
|
+
raise InvalidUsernameError, "Invalid Username: #{@username}"
|
69
|
+
end
|
70
|
+
|
71
|
+
######################################################################
|
72
|
+
protected
|
73
|
+
######################################################################
|
74
|
+
|
75
|
+
#---------------------------------------------------------------------
|
76
|
+
def _username_prompt opts
|
77
|
+
prompt = 'Username: '
|
78
|
+
case opts[:prompt]
|
79
|
+
when nil, :default
|
80
|
+
when :auto
|
81
|
+
unless @hostname.nil?
|
82
|
+
'(' + @hostname + ') ' + prompt
|
83
|
+
end
|
84
|
+
else
|
85
|
+
prompt = opts[:prompt]
|
86
|
+
end
|
87
|
+
prompt
|
88
|
+
end
|
89
|
+
|
90
|
+
end # helper
|
91
|
+
end # namespace
|
92
|
+
end # package
|
93
|
+
############################################################################
|
@@ -0,0 +1,58 @@
|
|
1
|
+
############################################################################
|
2
|
+
require 'ghaki/account/base'
|
3
|
+
require 'ghaki/account/userdomain'
|
4
|
+
require 'ghaki/account/domain_address'
|
5
|
+
|
6
|
+
############################################################################
|
7
|
+
module Ghaki
|
8
|
+
module Account
|
9
|
+
class WinDos < Base
|
10
|
+
include UserDomain
|
11
|
+
include DomainAddress
|
12
|
+
|
13
|
+
######################################################################
|
14
|
+
# CLASS METHODS
|
15
|
+
######################################################################
|
16
|
+
|
17
|
+
#---------------------------------------------------------------------
|
18
|
+
def self.from_opts opts
|
19
|
+
opts[:account] || WinDos.new(opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
#---------------------------------------------------------------------
|
23
|
+
def self.purge_opts opts ; super opts
|
24
|
+
UserDomain.purge_opts opts
|
25
|
+
DomainAddress.purge_opts opts
|
26
|
+
opts
|
27
|
+
end
|
28
|
+
|
29
|
+
######################################################################
|
30
|
+
# OBJECT METHODS
|
31
|
+
######################################################################
|
32
|
+
|
33
|
+
#---------------------------------------------------------------------
|
34
|
+
def expand_opts opts={} ; super opts
|
35
|
+
opts[:userdomain] = @userdomain unless @userdomain.nil?
|
36
|
+
opts[:domain_address] = @domain_address unless @domain_address.nil?
|
37
|
+
opts
|
38
|
+
end
|
39
|
+
|
40
|
+
#---------------------------------------------------------------------
|
41
|
+
def to_s
|
42
|
+
"\\\\" + (@userdomain || '*') + "\\" + (@username || '*')
|
43
|
+
end
|
44
|
+
|
45
|
+
######################################################################
|
46
|
+
protected
|
47
|
+
######################################################################
|
48
|
+
|
49
|
+
#---------------------------------------------------------------------
|
50
|
+
def _from_opts opts ; super opts
|
51
|
+
opt_userdomain opts
|
52
|
+
opt_domain_address opts
|
53
|
+
end
|
54
|
+
|
55
|
+
end # class
|
56
|
+
end # namespace
|
57
|
+
end # package
|
58
|
+
############################################################################
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'ghaki/account/base'
|
2
|
+
|
3
|
+
module Ghaki module Account module BaseTesting
|
4
|
+
describe Base do
|
5
|
+
|
6
|
+
########################################################################
|
7
|
+
# CONSTANTS
|
8
|
+
########################################################################
|
9
|
+
OPTS_HOS = { :hostname => 'host' }
|
10
|
+
OPTS_USR = { :username => 'user' }
|
11
|
+
OPTS_PAS = { :password => ['secret'] }
|
12
|
+
OPTS_EML = { :email_address => 'user@host' }
|
13
|
+
OPTS_H_U = OPTS_HOS.merge(OPTS_USR)
|
14
|
+
OPTS_ALL = OPTS_H_U.merge(OPTS_PAS).merge(OPTS_EML)
|
15
|
+
EXTRA_OPTS = { :extra => true }
|
16
|
+
|
17
|
+
########################################################################
|
18
|
+
# EIGEN TESTS
|
19
|
+
########################################################################
|
20
|
+
context 'eigen class' do
|
21
|
+
specify { Base.ancestors.should include(Hostname) }
|
22
|
+
specify { Base.ancestors.should include(Username) }
|
23
|
+
specify { Base.ancestors.should include(Password) }
|
24
|
+
specify { Base.ancestors.should include(EMailAddress) }
|
25
|
+
subject { Base }
|
26
|
+
it { should respond_to :from_opts }
|
27
|
+
it { should respond_to :purge_opts }
|
28
|
+
|
29
|
+
#---------------------------------------------------------------------
|
30
|
+
describe '#from_opts' do
|
31
|
+
it 'accepts separate login parts' do
|
32
|
+
acc = Base.from_opts(OPTS_ALL)
|
33
|
+
acc.hostname.should == 'host'
|
34
|
+
acc.username.should == 'user'
|
35
|
+
acc.password.should == 'secret'
|
36
|
+
end
|
37
|
+
it 'passes thru account object' do
|
38
|
+
acc = Base.from_opts(OPTS_ALL)
|
39
|
+
opts = { :account => acc }
|
40
|
+
Base.from_opts(opts).should == acc
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#---------------------------------------------------------------------
|
45
|
+
describe '#purge_opts' do
|
46
|
+
it 'removes separate login parts' do
|
47
|
+
Base.purge_opts(OPTS_ALL.merge(EXTRA_OPTS)).should eql(EXTRA_OPTS)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
########################################################################
|
54
|
+
# INSTANCE TESTS
|
55
|
+
########################################################################
|
56
|
+
context 'object instance' do
|
57
|
+
subject { Base.new }
|
58
|
+
|
59
|
+
it { should respond_to :ask_all }
|
60
|
+
|
61
|
+
#---------------------------------------------------------------------
|
62
|
+
it { should respond_to :to_s }
|
63
|
+
describe '#to_s' do
|
64
|
+
it 'creates from hostname only' do
|
65
|
+
Base.new(OPTS_HOS).to_s.should == '*@host'
|
66
|
+
end
|
67
|
+
it 'creates from username only' do
|
68
|
+
Base.new(OPTS_USR).to_s.should == 'user@*'
|
69
|
+
end
|
70
|
+
it 'creates from username and hostname' do
|
71
|
+
Base.new(OPTS_H_U).to_s.should == 'user@host'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#---------------------------------------------------------------------
|
76
|
+
describe '#email_address' do
|
77
|
+
it 'defaults with username only' do
|
78
|
+
Base.new(OPTS_USR).email_address.should == 'user'
|
79
|
+
end
|
80
|
+
it 'defaults with username and hostname' do
|
81
|
+
Base.new(OPTS_H_U).email_address.should == 'user@host'
|
82
|
+
end
|
83
|
+
it 'accepts full email address' do
|
84
|
+
Base.new(OPTS_EML).email_address.should == 'user@host'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
#---------------------------------------------------------------------
|
89
|
+
it { should respond_to :collapse_opts }
|
90
|
+
describe '#collapse_opts' do
|
91
|
+
before(:each) do
|
92
|
+
@base = Base.new(OPTS_ALL)
|
93
|
+
@opts = { :account => @base }
|
94
|
+
end
|
95
|
+
it 'generates account pair' do
|
96
|
+
@base.collapse_opts.should eql(@opts)
|
97
|
+
end
|
98
|
+
it 'ignores extra hash pairs' do
|
99
|
+
@base.collapse_opts(EXTRA_OPTS).should eql(@opts.merge(EXTRA_OPTS))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#---------------------------------------------------------------------
|
104
|
+
it { should respond_to :expand_opts }
|
105
|
+
describe '#expand_opts' do
|
106
|
+
before(:each) do
|
107
|
+
@base = Base.new(OPTS_ALL)
|
108
|
+
end
|
109
|
+
it 'generates separate login pairs' do
|
110
|
+
@base.expand_opts.should eql(OPTS_ALL)
|
111
|
+
end
|
112
|
+
it 'ignores extra hash pairs' do
|
113
|
+
@base.expand_opts(EXTRA_OPTS).should eql(OPTS_ALL.merge(EXTRA_OPTS))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end end end
|
121
|
+
############################################################################
|