pastehub 0.2.6 → 0.4.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.
@@ -1,171 +0,0 @@
1
- #
2
- # auth.rb - PasteHub's authentication library file
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
- require "openssl"
35
- require "base64"
36
- require 'pp'
37
-
38
- module PasteHub
39
- MANDATORY_KEYS = [
40
- 'x-pastehub-username',
41
- 'x-pastehub-date',
42
- 'x-pastehub-version'
43
- ]
44
-
45
-
46
- class Auth
47
- def initialize()
48
- @elements = Hash.new
49
- end
50
-
51
- def addElement( key, value )
52
- @elements[key.downcase] = value
53
- end
54
-
55
- def calcSignature( secretKey )
56
- a = Set.new( @elements.keys )
57
- b = Set.new( MANDATORY_KEYS )
58
- if a.superset?( b )
59
- message = MANDATORY_KEYS.sort.map {|k|
60
- k + ':' + @elements[k]
61
- }.join( ',' ).downcase
62
-
63
- h = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, secretKey, message)
64
- Base64.encode64(h).chomp
65
- else
66
- # not enough keys
67
- :NotEnoughKeys
68
- end
69
- end
70
-
71
- def getAuthHash( )
72
- @elements
73
- end
74
-
75
- def username()
76
- @elements['x-pastehub-username']
77
- end
78
-
79
- def curTime()
80
- @elements['x-pastehub-date']
81
- end
82
- end
83
-
84
- class AuthForClient
85
- def initialize( username, secretKey )
86
- util = Util.new
87
- @token = Auth.new( )
88
- @token.addElement( 'x-pastehub-username', username )
89
- @token.addElement( 'x-pastehub-date', util.key_seconds( util.currentTime( )).to_s )
90
- @token.addElement( 'x-pastehub-version', '2012-06-16' )
91
- @secretKey = secretKey
92
- end
93
-
94
- def getAuthHash( )
95
- sign = @token.calcSignature( @secretKey )
96
- #pp ["sign", sign ]
97
- if sign.is_a? String
98
- @token.addElement( 'Authorization', sign )
99
- @token.getAuthHash()
100
- else
101
- raise RuntimeError, "Error: can't create AuthForClient instance."
102
- end
103
- end
104
-
105
- # for Testing with RSpec.
106
- def _addElement( key, value )
107
- @token.addElement( key, value )
108
- end
109
-
110
- def username()
111
- @token.username
112
- end
113
- end
114
-
115
- class AuthForServer
116
- def initialize( users )
117
- # db connecter of Users table
118
- @users = users
119
- end
120
-
121
- def expired?( clientTime, serverTime )
122
- (60*5) < ( clientTime.to_i - serverTime.to_i ).abs
123
- end
124
-
125
- # return:
126
- # [ true/false, "username", :reason ]
127
- def invoke( hash, serverTime )
128
- auth = Auth.new
129
- client_sign = ""
130
- hash.each { |k,v|
131
- k = k.downcase
132
- #pp [ "invoke", k, v ]
133
- if MANDATORY_KEYS.include?( k )
134
- auth.addElement( k, v )
135
- end
136
- if 'authorization' == k
137
- client_sign = v
138
- end
139
- }
140
-
141
- #pp [ "auth.getAuthHash()", auth.getAuthHash() ]
142
- #pp [ "client_sign", client_sign ]
143
- #pp [ "auth.username", auth.username ]
144
-
145
- if not auth.username
146
- # fail... username was unspecified
147
- [ false, 'UNSPECIFIED', :unspecified_user ]
148
- else
149
- if @users.getSecretKey(auth.username)
150
- server_sign = auth.calcSignature( @users.getSecretKey(auth.username) )
151
- #pp [ "server_sign", server_sign ]
152
- if server_sign == client_sign
153
-
154
- if expired?( auth.curTime, serverTime )
155
- # authentication success
156
- [ false, auth.username, :expired_client_request ]
157
- else
158
- [ true, auth.username, :ok ]
159
- end
160
- else
161
- # fail...
162
- [ false, auth.username, :illegal_signature ]
163
- end
164
- else
165
- # unknown user
166
- [ false, auth.username, :unknown_user ]
167
- end
168
- end
169
- end
170
- end
171
- end
@@ -1,70 +0,0 @@
1
- #
2
- # crypt.rb - PasteHub's encrypt/decrypt library
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
- require 'openssl'
35
- require 'base64'
36
-
37
- module PasteHub
38
- class Crypt
39
- def initialize( password )
40
- @password = password
41
- @des3 = OpenSSL::Cipher.new('des3')
42
- end
43
-
44
- def en( str )
45
- if 0 == str.size
46
- ""
47
- else
48
- @des3.encrypt
49
- @des3.pkcs5_keyivgen( @password )
50
- Base64.encode64( @des3.update( str ) + @des3.final )
51
- end
52
- end
53
-
54
- def de( str )
55
- if 0 == str.size
56
- ""
57
- else
58
- begin
59
- @des3.decrypt
60
- @des3.pkcs5_keyivgen( @password )
61
- ret = @des3.update( Base64.decode64( str ))
62
- ret += @des3.final
63
- rescue OpenSSL::Cipher::CipherError => e
64
- ret = nil
65
- end
66
- ret
67
- end
68
- end
69
- end
70
- end
@@ -1,187 +0,0 @@
1
- #
2
- # localdb.rb - PasteHub's localdb manager
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
- require 'gdbm'
35
-
36
- module PasteHub
37
- class MutexSingleton
38
- include Singleton
39
-
40
- attr_reader :mutex
41
-
42
- def self.instance
43
- @@instance ||= new
44
- end
45
-
46
- def initialize( )
47
- @mutex = Mutex.new
48
- end
49
- end
50
-
51
- ONLINE_STATE_KEY='__ONLINE_STATE'
52
- LOCAL_DATE_KEY ='__LOCAL_DATE'
53
- SERVER_DATE_KEY ='__SERVER_DATE'
54
-
55
- LOCAL_PREFIX = "local::"
56
- SERVER_PREFIX = "server::"
57
-
58
- class LocalDB
59
- def initialize( basepath = "/tmp/")
60
- @mutex = MutexSingleton.instance.mutex
61
- @basepath = basepath
62
- end
63
-
64
- def open( username, reader = false )
65
- closed = false
66
- (60*2).times { |n|
67
- @mutex.synchronize {
68
- if reader
69
- @db = GDBM.new( @basepath + username + ".db", nil, GDBM::READER | GDBM::NOLOCK )
70
- else
71
- @db = GDBM.new( @basepath + username + ".db", nil, GDBM::WRCREAT )
72
- end
73
- closed = @db.closed?
74
- }
75
- break unless closed
76
- #STDERR.puts "#Warning: DB open fail(locked) retry..."
77
- sleep 0.5
78
- }
79
- @mutex.synchronize {
80
- closed = @db.closed?
81
- }
82
- if closed
83
- raise RuntimeError, sprintf( "DBM.new open error: file=%s", username + ".db" )
84
- end
85
- @username = username
86
- end
87
-
88
- def getList( limit = nil )
89
- arr = self._getList().reject{|x| x.match( /^_/ )}
90
- if limit
91
- arr.take( limit )
92
- else
93
- arr
94
- end
95
- end
96
-
97
- def _getList( )
98
- forward_match_keys( LOCAL_PREFIX ).sort {|a,b| -(a <=> b) }.map {|x|
99
- x[(LOCAL_PREFIX.size)...(x.size)]
100
- }
101
- end
102
-
103
- def getServerList( )
104
- self._getServerList().reject{|x| x.match( /^_/ )}
105
- end
106
-
107
- def _getServerList( )
108
- forward_match_keys( SERVER_PREFIX ).sort {|a,b| -(a <=> b) }.map {|x|
109
- x[(SERVER_PREFIX.size)...(x.size)]
110
- }
111
- end
112
-
113
- def getValue( key, fallback = false )
114
- val = nil
115
- @mutex.synchronize {
116
- val = @db[ LOCAL_PREFIX + key ]
117
- }
118
- if val
119
- val.force_encoding("UTF-8")
120
- else
121
- fallback
122
- end
123
- end
124
-
125
- def insertValue( key, value )
126
- @mutex.synchronize {
127
- @db[ LOCAL_PREFIX + key.force_encoding("ASCII-8BIT") ] = value.force_encoding("ASCII-8BIT")
128
- }
129
- end
130
-
131
- def deleteValue( key )
132
- ret = false
133
- @mutex.synchronize {
134
- val = @db[ LOCAL_PREFIX + key ]
135
- if val
136
- @db.delete( LOCAL_PREFIX + key )
137
- ret = true
138
- else
139
- ret = false
140
- end
141
- }
142
- ret
143
- end
144
-
145
- def setServerFlag( key )
146
- @mutex.synchronize {
147
- @db[ SERVER_PREFIX + key ] = '1'
148
- }
149
- end
150
-
151
- def onServer?( key )
152
- ret = false
153
- @mutex.synchronize {
154
- if @db[ SERVER_PREFIX + key ]
155
- ret = true
156
- else
157
- ret = false
158
- end
159
- }
160
- ret
161
- end
162
-
163
- def forward_match_keys( prefix )
164
- keys = []
165
- @mutex.synchronize {
166
- keys = @db.keys( ).select {|key|
167
- key.match( "^" + prefix )
168
- }
169
- }
170
- keys
171
- end
172
-
173
- def clear
174
- @mutex.synchronize {
175
- @db.clear
176
- }
177
- end
178
-
179
- def close
180
- ret = nil
181
- @mutex.synchronize {
182
- ret = @db.close
183
- }
184
- ret
185
- end
186
- end
187
- end
@@ -1,95 +0,0 @@
1
- #
2
- # log.rb - PasteHub's log manager
3
- #
4
- # Copyright (c) 2009-2011 Kiyoka Nishiyama <kiyoka@sumibi.org>
5
- #
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions
8
- # are met:
9
- #
10
- # 1. Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- #
13
- # 2. Redistributions in binary form must reproduce the above copyright
14
- # notice, this list of conditions and the following disclaimer in the
15
- # documentation and/or other materials provided with the distribution.
16
- #
17
- # 3. Neither the name of the authors nor the names of its contributors
18
- # may be used to endorse or promote products derived from this
19
- # software without specific prior written permission.
20
- #
21
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27
- # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
- # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
- #
33
- #
34
-
35
- module PasteHub
36
- class LogBase
37
- def initialize( hash )
38
- @user = nil
39
- if hash.is_a? Hash
40
- if hash.has_key?( :user )
41
- @user = hash[ :user ]
42
- else
43
- @user = 'UNSPECIFIED'
44
- end
45
- if hash.has_key?( :api )
46
- @api = hash[ :api ]
47
- else
48
- raise ArgumentError if not @api
49
- end
50
- else
51
- raise ArgumentError
52
- end
53
-
54
- @uri = URI.parse( "http://localhost:9880/pastehub.webapi" )
55
- @http = Net::HTTP.new(@uri.host, @uri.port)
56
- #Fluent::Logger::FluentLogger.open(nil, :host=>'localhost', :port=>24224)
57
- end
58
-
59
- def write( hashData )
60
- begin
61
- jsonStr = hashData.to_json
62
- resp = @http.post( @uri.request_uri, "json=" + jsonStr )
63
- if "200" != resp.code
64
- STDERR.print "Error: can't post to fluentd(http)[1].\n"
65
- end
66
- rescue
67
- STDERR.print "Error: can't post to fluentd(http)[2].\n"
68
- end
69
- #Fluent::Logger.post("pastehub.webapi", hashData)
70
- true
71
- end
72
- end
73
-
74
- class Log < LogBase
75
- # info without error
76
- def info( message, moreHash = {} )
77
- hashData = {
78
- "user"=>"#{@user}",
79
- "api"=>"#{@api}",
80
- "message"=>"#{message}",
81
- "error" => false}
82
- write( hashData.merge( moreHash ) )
83
- end
84
-
85
- # errors
86
- def error( message, moreHash = {} )
87
- hashData = {
88
- "user"=>"#{@user}",
89
- "api"=>"#{@api}",
90
- "message"=>"#{message}",
91
- "error" => true}
92
- write( hashData.merge( moreHash ) )
93
- end
94
- end
95
- end