impostor 0.2.1 → 1.0.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.
Files changed (108) hide show
  1. data/.gemtest +0 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +47 -0
  7. data/History.txt +8 -0
  8. data/Manifest.txt +87 -55
  9. data/README.txt +11 -11
  10. data/Rakefile +16 -20
  11. data/lib/impostor/auth.rb +103 -0
  12. data/lib/impostor/config.rb +171 -0
  13. data/lib/impostor/errors.rb +67 -0
  14. data/lib/impostor/phpbb2.rb +202 -0
  15. data/lib/impostor/phpbb3.rb +199 -0
  16. data/lib/impostor/post.rb +111 -0
  17. data/lib/impostor/topic.rb +115 -0
  18. data/lib/impostor/wwf79.rb +186 -0
  19. data/lib/impostor/wwf80.rb +190 -0
  20. data/lib/impostor.rb +108 -5
  21. data/spec/auth_spec.rb +148 -0
  22. data/spec/base_spec_helper.rb +12 -0
  23. data/{test/test_helper.rb → spec/caged_net_http.rb} +8 -17
  24. data/spec/config_spec.rb +136 -0
  25. data/spec/fixtures/junk.html +1 -0
  26. data/{test → spec}/fixtures/phpbb2-get-new_topic-form-good-response.html +0 -0
  27. data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-good-response.html +11 -11
  28. data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-malformed-response.html +0 -0
  29. data/{test → spec}/fixtures/phpbb2-index.html +0 -0
  30. data/{test → spec}/fixtures/phpbb2-logged-in.html +0 -0
  31. data/{test → spec}/fixtures/phpbb2-login.html +0 -0
  32. data/{test → spec}/fixtures/phpbb2-not-logged-in.html +0 -0
  33. data/{test → spec}/fixtures/phpbb2-post-new_topic-good-response.html +0 -0
  34. data/{test → spec}/fixtures/phpbb2-post-reply-good-response.html +0 -0
  35. data/{test → spec}/fixtures/phpbb2-post-reply-throttled-response.html +0 -0
  36. data/{test → spec}/fixtures/phpbb2-too-many-posts.html +0 -0
  37. data/{test → spec}/fixtures/phpbb3-get-new-topic-form-good-response.html +0 -0
  38. data/{test → spec}/fixtures/phpbb3-get-reply-form-good-response.html +0 -0
  39. data/{test → spec}/fixtures/phpbb3-logged-in.html +0 -0
  40. data/{test → spec}/fixtures/phpbb3-login.html +0 -0
  41. data/{test → spec}/fixtures/phpbb3-not-logged-in.html +0 -0
  42. data/{test → spec}/fixtures/phpbb3-post-new_topic-good-response.html +0 -0
  43. data/{test → spec}/fixtures/phpbb3-post-reply-good-response.html +0 -0
  44. data/spec/fixtures/vcr_cassettes/phpbb2-should-be-overlimit-creating-topic.yml +1308 -0
  45. data/spec/fixtures/vcr_cassettes/phpbb2-should-create-topic.yml +923 -0
  46. data/spec/fixtures/vcr_cassettes/phpbb2-should-login.yml +360 -0
  47. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-create-new-topic.yml +497 -0
  48. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-login.yml +287 -0
  49. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-post.yml +497 -0
  50. data/spec/fixtures/vcr_cassettes/phpbb2-should-overlimit-error-post.yml +1140 -0
  51. data/spec/fixtures/vcr_cassettes/phpbb2-should-post.yml +751 -0
  52. data/spec/fixtures/vcr_cassettes/phpbb3-should-be-overlimit-creating-topic.yml +995 -0
  53. data/spec/fixtures/vcr_cassettes/phpbb3-should-create-topic.yml +675 -0
  54. data/spec/fixtures/vcr_cassettes/phpbb3-should-login.yml +245 -0
  55. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-create-new-topic.yml +350 -0
  56. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-login.yml +253 -0
  57. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-post.yml +350 -0
  58. data/spec/fixtures/vcr_cassettes/phpbb3-should-overlimit-error-post.yml +1046 -0
  59. data/spec/fixtures/vcr_cassettes/phpbb3-should-post.yml +605 -0
  60. data/{test → spec}/fixtures/wwf79-forum_posts.html +0 -0
  61. data/{test → spec}/fixtures/wwf79-general-new-topic-error.html +0 -0
  62. data/{test → spec}/fixtures/wwf79-general-posting-error.html +0 -0
  63. data/{test → spec}/fixtures/wwf79-good-post-forum_posts.html +1 -1
  64. data/{test → spec}/fixtures/wwf79-index.html +0 -0
  65. data/{test → spec}/fixtures/wwf79-logged-in.html +0 -0
  66. data/{test → spec}/fixtures/wwf79-login.html +0 -0
  67. data/{test → spec}/fixtures/wwf79-new-topic-forum_posts-response.html +0 -0
  68. data/{test → spec}/fixtures/wwf79-new-topic-post_message_form.html +0 -0
  69. data/{test → spec}/fixtures/wwf79-not-logged-in.html +0 -0
  70. data/{test → spec}/fixtures/wwf79-too-many-posts.html +0 -0
  71. data/{test → spec}/fixtures/wwf79-too-many-topics.html +0 -0
  72. data/{test → spec}/fixtures/wwf80-general-posting-error.html +0 -0
  73. data/{test → spec}/fixtures/wwf80-get-new_topic-form-good-response.html +0 -0
  74. data/{test → spec}/fixtures/wwf80-get-viewtopic-for-new-topic-good-response.html +0 -0
  75. data/{test → spec}/fixtures/wwf80-index.html +0 -0
  76. data/{test → spec}/fixtures/wwf80-logged-in.html +0 -0
  77. data/{test → spec}/fixtures/wwf80-login.html +0 -0
  78. data/{test → spec}/fixtures/wwf80-new_reply_form.html +0 -0
  79. data/{test → spec}/fixtures/wwf80-not-logged-in.html +0 -0
  80. data/{test → spec}/fixtures/wwf80-post-new_topic-good-response.html +1 -1
  81. data/{test → spec}/fixtures/wwf80-post-reply-good-response.html +0 -0
  82. data/{test → spec}/fixtures/wwf80-too-many-posts.html +0 -0
  83. data/spec/impostor_spec_helper.rb +162 -0
  84. data/spec/integration/phpbb2_spec.rb +111 -0
  85. data/spec/integration/phpbb3_spec.rb +109 -0
  86. data/spec/integration_spec_helper.rb +7 -0
  87. data/spec/phpbb2_spec.rb +346 -0
  88. data/spec/phpbb3_spec.rb +332 -0
  89. data/spec/post_spec.rb +134 -0
  90. data/spec/spec_helper.rb +2 -0
  91. data/spec/test_impostor.rb +12 -0
  92. data/spec/topic_spec.rb +143 -0
  93. data/spec/wwf79_spec.rb +342 -0
  94. data/spec/wwf80_spec.rb +339 -0
  95. metadata +156 -87
  96. data/lib/www/impostor/phpbb2.rb +0 -258
  97. data/lib/www/impostor/phpbb3.rb +0 -236
  98. data/lib/www/impostor/wwf79.rb +0 -254
  99. data/lib/www/impostor/wwf80.rb +0 -264
  100. data/lib/www/impostor.rb +0 -269
  101. data/test/test_github.rb +0 -12
  102. data/test/test_www_impostor.rb +0 -165
  103. data/test/test_www_impostor_phpbb2.rb +0 -536
  104. data/test/test_www_impostor_phpbb3.rb +0 -483
  105. data/test/test_www_impostor_wwf79.rb +0 -535
  106. data/test/test_www_impostor_wwf80.rb +0 -535
  107. data/vendor/plugins/impostor/lib/autotest/discover.rb +0 -3
  108. data/vendor/plugins/impostor/lib/autotest/impostor.rb +0 -49
@@ -1,258 +0,0 @@
1
- require 'rubygems'
2
- require 'hpricot'
3
- gem 'mechanize', '>= 0.7.0'
4
- require 'mechanize'
5
- require 'cgi'
6
-
7
- ##
8
- # phpBB2 version of the Impostor
9
- #
10
-
11
- class WWW::Impostor
12
-
13
- class Phpbb2 < WWW::Impostor
14
-
15
- ##
16
- # After initializing the parent a mechanize agent is created
17
- #
18
- # Additional configuration parameters:
19
- #
20
- # :posting_page
21
- #
22
- # Typical configuration parameters
23
- # { :type => :phpbb2,
24
- # :app_root => 'http://example.com/forum/',
25
- # :login_page => 'login.php',
26
- # :posting_page => 'posting.php',
27
- # :user_agent => 'Windows IE 7',
28
- # :username => 'myuser',
29
- # :password => 'mypasswd' }
30
-
31
- def initialize(config={})
32
- super(config)
33
- @agent = WWW::Mechanize.new
34
- @agent.user_agent_alias = user_agent
35
- # jar is a yaml file
36
- @agent.cookie_jar.load(cookie_jar) if cookie_jar && File.exist?(cookie_jar)
37
- @message = nil
38
- @loggedin = false
39
- end
40
-
41
- ##
42
- # clean up the state of the library and log out
43
-
44
- def logout
45
- return false unless @loggedin
46
-
47
- @agent.cookie_jar.save_as(cookie_jar) if cookie_jar
48
- save_topics
49
-
50
- @forum = nil
51
- @topic = nil
52
- @message = nil
53
-
54
- @loggedin = false
55
- true
56
- end
57
-
58
- ##
59
- # make a new topic
60
-
61
- def new_topic(forum=@forum, subject=@subject, message=@message)
62
- raise PostError.new("forum not set") unless forum
63
- raise PostError.new("topic name not given") unless subject
64
- raise PostError.new("message not set") unless message
65
-
66
- login
67
- raise PostError.new("not logged in") unless @loggedin
68
-
69
- uri = posting_page
70
- uri.query = "mode=newtopic&f=#{forum}"
71
-
72
- # get the submit form
73
- begin
74
- page = @agent.get(uri)
75
- rescue StandardError => err
76
- raise PostError.new(err)
77
- end
78
-
79
- form = page.form('post') rescue nil
80
- button = form.buttons.with.name('post').first rescue nil
81
- raise PostError.new("post form not found") unless button && form
82
-
83
- # set up the form and submit it
84
- form.subject = subject
85
- form.message = message
86
- form['disable_html'] = nil
87
- form['disable_bbcode'] = 'on'
88
- form['disable_smilies'] = 'on'
89
- begin
90
- page = @agent.submit(form, button)
91
- rescue StandardError => err
92
- raise PostError.new(err)
93
- end
94
-
95
- # if the response is correct there will be a meta link that looks something like
96
- # <meta http-equiv="refresh" content="3;url=viewtopic.php?p=29#29">
97
- #
98
- # this link needs to be followed, the page it leads to will give us
99
- # the topic id that was created for the topic name that we created
100
- a = (page.search("//meta[@http-equiv='refresh']").attr('content') rescue nil)
101
- a = (/url=(.*)/.match(a)[1] rescue nil)
102
- raise PostError.new('unexpected new topic response from refresh') unless a
103
-
104
- a = URI.join(app_root, a)
105
- page = @agent.get(a)
106
- link = (page.search("//link[@rel='prev']").first['href'] rescue nil)
107
- raise PostError.new('unexpected new topic response from link prev') unless link
108
-
109
- # t=XXX will be our new topic id, i.e.
110
- # <link rel="prev" href="http://localhost/phpBB2/viewtopic.php?t=5&amp;view=previous" title="View previous topic"
111
- u = (URI.parse(link) rescue nil)
112
- topic = (CGI::parse(u.query)['t'][0] rescue nil)
113
- topic = topic.to_i
114
- raise PostError.new('unexpected new topic ID') unless topic > 0
115
-
116
- # save new topic id and topic name
117
- add_subject(forum, topic, subject)
118
- @forum=forum; @topic=topic; @subject=subject; @message=message
119
- true
120
- end
121
-
122
- ##
123
- # Attempt to post to the forum
124
-
125
- def post(forum = @forum, topic = @topic, message = @message)
126
- raise PostError.new("forum not set") unless forum
127
- raise PostError.new("topic not set") unless topic
128
- raise PostError.new("message not set") unless message
129
-
130
- login
131
- raise PostError.new("not logged in") unless @loggedin
132
-
133
- uri = posting_page
134
- uri.query = "mode=reply&t=#{topic}"
135
-
136
- # get the submit form
137
- begin
138
- page = @agent.get(uri)
139
- rescue StandardError => err
140
- raise PostError.new(err)
141
- end
142
-
143
- form = page.form('post') rescue nil
144
- button = form.buttons.with.name('post').first rescue nil
145
- raise PostError.new("post form not found") unless button && form
146
-
147
- # set up the form and submit it
148
- form.message = message
149
- form['disable_html'] = nil
150
- form['disable_bbcode'] = 'on'
151
- form['disable_smilies'] = 'on'
152
- begin
153
- page = @agent.submit(form, button)
154
- rescue StandardError => err
155
- raise PostError.new(err)
156
- end
157
-
158
- mes = page.search("//span[@class='gen']").last
159
- posted = mes.innerText =~ /Your message has been entered successfully./ rescue false
160
- if posted
161
- @forum=forum; @topic=topic; @subject=get_subject(forum,topic); @message=message
162
- return true
163
- end
164
-
165
- too_many = (mes.innerText =~
166
- /You cannot make another post so soon after your last; please try again in a short while./ rescue
167
- false)
168
- raise ThrottledError.new("too many posts in too short amount of time") if too_many
169
-
170
- # false otherwise, should we raise an exception instead?
171
- false
172
- end
173
-
174
- ##
175
- # Get the posting page for the application (specific to phpBB2)
176
-
177
- def posting_page
178
- URI.join(app_root, config[:posting_page])
179
- end
180
-
181
- ##
182
- # does the work of logging into phpbb
183
-
184
- def login
185
- return true if @loggedin
186
-
187
- # get the login page
188
- page = fetch_login_page
189
-
190
- # return if we are already logged in from a cookie state
191
- return true if logged_in?(page)
192
-
193
- # setup the form and submit
194
- form, button = login_form_and_button(page)
195
- page = post_login(form, button)
196
-
197
- # set up the rest of the state if we are logged in
198
- @loggedin = logged_in?(page)
199
- load_topics if @loggedin
200
-
201
- @loggedin
202
- end
203
-
204
- def version
205
- @version ||= self.class.to_s
206
- end
207
-
208
- protected
209
-
210
- ##
211
- # does the work of posting the login form
212
-
213
- def post_login(form, button)
214
- begin
215
- page = @agent.submit(form, button)
216
- rescue StandardError => err
217
- raise LoginError.new(err)
218
- end
219
- end
220
-
221
- ##
222
- # returns the login form and its button from the login page
223
-
224
- def login_form_and_button(page)
225
- form = page.forms.first rescue nil
226
- raise LoginError.new("unknown login page format") unless form
227
-
228
- button = page.forms.first.buttons.with.name('login').first
229
- form['username'] = username
230
- form['password'] = password
231
- form['autologin'] = 'on'
232
-
233
- return form, button
234
- end
235
-
236
- ##
237
- # fetches the login page
238
-
239
- def fetch_login_page
240
- begin
241
- page = @agent.get(login_page)
242
- rescue StandardError => err
243
- raise LoginError.new(err)
244
- end
245
- end
246
-
247
- ##
248
- # Checks if the agent is already logged by stored cookie
249
-
250
- def logged_in?(page)
251
- mm = page.search( "//a" ).detect{|a| a.inner_html =~ /Log out \[ #{username} \]/i}
252
- mm ||= page.search( "//a" ).detect{|a| a['href'] =~ /\/login\.php\?logout=true/}
253
-
254
- mm.nil? ? false : true
255
- end
256
-
257
- end
258
- end
@@ -1,236 +0,0 @@
1
- require 'rubygems'
2
- require 'hpricot'
3
- gem 'mechanize', '>= 0.7.0'
4
- require 'mechanize'
5
- require 'cgi'
6
-
7
- ##
8
- # phpBB3 version of the Impostor
9
- #
10
-
11
- class WWW::Impostor
12
-
13
- class Phpbb3 < WWW::Impostor
14
-
15
- ##
16
- # After initializing the parent a mechanize agent is created
17
- #
18
- # Additional configuration parameters:
19
- #
20
- # :posting_page
21
- #
22
- # Typical configuration parameters
23
- # { :type => :phpbb3,
24
- # :app_root => 'http://example.com/forum/',
25
- # :login_page => 'ucp.php?mode=login',
26
- # :posting_page => 'posting.php',
27
- # :user_agent => 'Windows IE 7',
28
- # :username => 'myuser',
29
- # :password => 'mypasswd' }
30
-
31
- def initialize(config={})
32
- super(config)
33
- @agent = WWW::Mechanize.new
34
- @agent.user_agent_alias = user_agent
35
- # jar is a yaml file
36
- @agent.cookie_jar.load(cookie_jar) if cookie_jar && File.exist?(cookie_jar)
37
- @message = nil
38
- @loggedin = false
39
- end
40
-
41
- ##
42
- # clean up the state of the library and log out
43
-
44
- def logout
45
- return false unless @loggedin
46
-
47
- @agent.cookie_jar.save_as(cookie_jar) if cookie_jar
48
- save_topics
49
-
50
- @forum = nil
51
- @topic = nil
52
- @message = nil
53
-
54
- @loggedin = false
55
- true
56
- end
57
-
58
- ##
59
- # make a new topic
60
-
61
- def new_topic(forum=@forum, subject=@subject, message=@message)
62
- raise PostError.new("forum not set") unless forum
63
- raise PostError.new("topic name not given") unless subject
64
- raise PostError.new("message not set") unless message
65
-
66
- login
67
- raise PostError.new("not logged in") unless @loggedin
68
-
69
- uri = posting_page
70
- uri.query = "mode=post&f=#{forum}"
71
-
72
- # get the submit form
73
- begin
74
- page = @agent.get(uri)
75
- rescue StandardError => err
76
- raise PostError.new(err)
77
- end
78
-
79
- form = page.form('postform') rescue nil
80
- raise PostError.new("post form not found") unless form
81
- button = form.buttons.detect{|b| b.name == 'post'}
82
- raise PostError.new("post form button not found") unless button
83
-
84
- # set up the form and submit it
85
- form['subject'] = subject
86
- form['message'] = message
87
- form['lastclick'] = (form['lastclick'].to_i - 60).to_s
88
-
89
- begin
90
- page = @agent.submit(form, button)
91
- rescue StandardError => err
92
- raise PostError.new(err)
93
- end
94
-
95
- # new topic will be current page uri since phpbb3 will 302 to the new
96
- # topic page, e.g.
97
- # http://example.com/forum/viewtopic.php?f=37&t=52
98
- topic = page.uri.query.split('&').detect{|a| a =~ /^t=/}.split('=').last.to_i rescue 0
99
- raise PostError.new('unexpected new topic ID') unless topic > 0
100
-
101
- # save new topic id and topic name
102
- add_subject(forum, topic, subject)
103
- @forum=forum; @topic=topic; @subject=subject; @message=message
104
- true
105
- end
106
-
107
- ##
108
- # Attempt to post to the forum
109
-
110
- def post(forum = @forum, topic = @topic, message = @message)
111
- raise PostError.new("forum not set") unless forum
112
- raise PostError.new("topic not set") unless topic
113
- raise PostError.new("message not set") unless message
114
-
115
- login
116
- raise PostError.new("not logged in") unless @loggedin
117
-
118
- uri = posting_page
119
- uri.query = "mode=reply&f=#{forum}&t=#{topic}"
120
-
121
- # get the submit form
122
- begin
123
- page = @agent.get(uri)
124
- rescue StandardError => err
125
- raise PostError.new(err)
126
- end
127
-
128
- form = page.form('postform') rescue nil
129
- button = form.buttons.with.name('post').first rescue nil
130
- raise PostError.new("post form not found") unless button && form
131
-
132
- # set up the form and submit it
133
- form.message = message
134
- form['lastclick'] = (form['lastclick'].to_i - 60).to_s
135
-
136
- begin
137
- page = @agent.submit(form, button)
138
- rescue StandardError => err
139
- raise PostError.new(err)
140
- end
141
-
142
- # new post will be in current page uri since phpbb3 will 302 to the new
143
- # post page post anchor, e.g.
144
- # http://example.com/forum/viewtopic.php?f=37&t=52&p=3725#p3725
145
- postid = page.uri.query.split('&').detect{|a| a =~ /^p=/}.split('=').last.to_i rescue 0
146
- raise PostError.new("message did not post") unless postid > 0
147
-
148
- @forum=forum; @topic=topic; @subject=get_subject(forum,topic); @message=message
149
-
150
- true
151
- end
152
-
153
- ##
154
- # Get the posting page for the application (specific to phpBB3)
155
-
156
- def posting_page
157
- URI.join(app_root, config[:posting_page])
158
- end
159
-
160
- ##
161
- # does the work of logging into phpbb
162
-
163
- def login
164
- return true if @loggedin
165
-
166
- # get the login page
167
- page = fetch_login_page
168
-
169
- # return if we are already logged in from a cookie state
170
- return true if logged_in?(page)
171
-
172
- # setup the form and submit
173
- form, button = login_form_and_button(page)
174
- page = post_login(form, button)
175
-
176
- # set up the rest of the state if we are logged in
177
- @loggedin = logged_in?(page)
178
- load_topics if @loggedin
179
-
180
- @loggedin
181
- end
182
-
183
- def version
184
- @version ||= self.class.to_s
185
- end
186
-
187
- protected
188
- ##
189
- # does the work of posting the login form
190
-
191
- def post_login(form, button)
192
- begin
193
- page = @agent.submit(form, button)
194
- rescue StandardError => err
195
- raise LoginError.new(err)
196
- end
197
- end
198
-
199
- ##
200
- # returns the login form and its button from the login page
201
-
202
- def login_form_and_button(page)
203
- form = page.forms.first rescue nil
204
- raise LoginError.new("unknown login page format") unless form
205
-
206
- button = form.buttons.with.name('login').first
207
- form['username'] = username
208
- form['password'] = password
209
- form['autologin'] = 'on'
210
-
211
- return form, button
212
- end
213
-
214
- ##
215
- # fetches the login page
216
-
217
- def fetch_login_page
218
- begin
219
- page = @agent.get(login_page)
220
- rescue StandardError => err
221
- raise LoginError.new(err)
222
- end
223
- end
224
-
225
- ##
226
- # Checks if the agent is already logged by stored cookie
227
-
228
- def logged_in?(page)
229
- mm = page.search( "//a" ).detect{|a| a.inner_html =~ /Logout \[ #{username} \]/}
230
- mm ||= page.search( "//a" ).detect{|a| a['href'] =~ /\.\/ucp.php\?mode=logout/}
231
-
232
- mm.nil? ? false : true
233
- end
234
-
235
- end
236
- end