mediawiki-butt 2.0.1 → 3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f656d4e90befce4bfef592c187829a7d713f882
4
- data.tar.gz: 53d0bdd862b94dd38e9f37c977e0da4b0df728ca
3
+ metadata.gz: 7716798bbc8877e9a116dfde230ca4a4db7a9914
4
+ data.tar.gz: 75fa4f657ee01443634762697672f8142d0c9387
5
5
  SHA512:
6
- metadata.gz: f0bfa18ec1ab7865eb3100ff54e73a729805cf6f06e2cd51c7c04775bea35283ee3501960ea7b848727a7f4e39f95637e1a91096b64c12e92052e374406a5d79
7
- data.tar.gz: 42615b44eb28fcca27d8b4ee274af367a5bf7a263a92ab3690b9d4838c8b8885522e1bd4eb0939eda12bb3393efda12f4203c026953ae2e3f8b64c7d942dc9df
6
+ metadata.gz: af78a66c15e2ba113cbb140037d1ca1294aa740d93e5a089dc2881228a3c087cb293aaa61fa574441217afe295affe93a6aa35055ebd7f31921a1032b9bd270e
7
+ data.tar.gz: 45e1c4885a3cf8e7ba01523573d60899b246b03ec49471efd98e8911275ab84496190adba89037e80216d2dc39a10de2e43716d856e6d6d5a13bcc4883ba730f
data/CHANGELOG.md CHANGED
@@ -1,4 +1,18 @@
1
1
  # Changelog
2
+ ## Version 3
3
+ ### Version 3.0.0
4
+ **Breaking changes!**
5
+ * Update token system for MediaWiki 1.27+ (#45, #46, #65, #67).
6
+ * `login` no longer takes a third `token` parameter.
7
+ * `create_account` no longer takes a fifth `token` parameter.
8
+ * `create_account_email` no longer takes a fifth `token` parameter.
9
+ * `MediaWiki::Query::Properties#get_token` has been replaced by `MediaWiki::Query::Meta#get_token`. This only takes one parameter, as opposed to the old method's two parameters, which is the type of token to receive. Valid types are verified in the `MediaWiki::Query::Meta::TOKEN_TYPES` array.
10
+ * Remove unnecessary `autoparse`, `header`, and `override_assertion` parameters from `post` (#68).
11
+ * The returned value is now always a parsed hash, never an HTTPMessage directly.
12
+ * Initialization parameter defaults are more likely what is to be used now (#62, #66).
13
+ * `:query_limit_default` is now defaulted to `'max'`.
14
+ * `:use_continuation` is now defaulted to `true`.
15
+
2
16
  ## Version 2
3
17
  ### Version 2.0.1
4
18
  * Fix NoMethodError in `get_templates_in_page` when called for pages with no templates (#61)
@@ -17,7 +17,7 @@ module MediaWiki
17
17
  expiry: expiry
18
18
  }
19
19
 
20
- token = get_token('block')
20
+ token = get_token
21
21
  params[:reason] = reason if reason
22
22
  params[:nocreate] = '1' if nocreate
23
23
  params[:token] = token
@@ -43,7 +43,7 @@ module MediaWiki
43
43
  action: 'unblock',
44
44
  user: user
45
45
  }
46
- token = get_token('unblock')
46
+ token = get_token
47
47
  params[:reason] = reason if reason
48
48
  params[:token] = token
49
49
 
@@ -5,34 +5,30 @@ module MediaWiki
5
5
  # Logs the user into the wiki. This is generally required for editing and getting restricted data.
6
6
  # @param username [String] The username
7
7
  # @param password [String] The password
8
- # @param token [String] The login token to use. Only set this if you know what you are doing. You probably want
9
- # to just let the function get the token and set it on its own.
10
- # @see #check_login
11
8
  # @see https://www.mediawiki.org/wiki/API:Login MediaWiki Login API Docs
12
9
  # @since 0.1.0
13
10
  # @raise [AuthenticationError]
14
11
  # @return [Boolean] True if the login was successful.
15
- def login(username, password, token = nil)
12
+ def login(username, password)
13
+ # Save the assertion value while trying to log in, because otherwise the assertion will prevent us from logging in
14
+ assertion_value = @assertion.clone
15
+ @assertion = nil
16
+
16
17
  params = {
17
18
  action: 'login',
18
19
  lgname: username,
19
- lgpassword: password
20
+ lgpassword: password,
21
+ lgtoken: get_token('login')
20
22
  }
21
- params[:lgtoken] = token if token
22
- header = {}
23
- header['Set-Cookie'] = @cookie if @cookie
24
23
 
25
- response = post(params, true, header, true)
26
- result = response['login']['result']
24
+ response = post(params)
27
25
 
28
- if result == 'NeedToken'
29
- token = response['login']['token']
30
- return login(username, password, token)
31
- end
26
+ @assertion = assertion_value
27
+
28
+ result = response['login']['result']
32
29
 
33
30
  if result == 'Success'
34
- @cookie = "#{response['login']['cookieprefix']}Session=#{response['login']['sessionid']}"
35
- @name = username
31
+ @name = response['login']['lgusername']
36
32
  @logged_in = true
37
33
  return true
38
34
  end
@@ -50,7 +46,7 @@ module MediaWiki
50
46
  action: 'logout'
51
47
  }
52
48
 
53
- post(params, true, nil, true)
49
+ post(params)
54
50
  @logged_in = false
55
51
 
56
52
  true
@@ -65,18 +61,16 @@ module MediaWiki
65
61
  # @param language [String] The language code to be set as default for the account. Defaults to 'en', or English.
66
62
  # Use the language code, not the name.
67
63
  # @param reason [String] The reason for creating the account, as shown in the account creation log. Optional.
68
- # @param token [String] The account creation token to use. Only set this if you know what you are doing. You
69
- # probably want to just let the function get the token and set it on its own.
70
64
  # @see #check_create
71
65
  # @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
72
66
  # @since 0.1.0
73
67
  # @return [Boolean] True if successful, false if not.
74
- def create_account(username, password, language = 'en', reason = nil, token = '')
68
+ def create_account(username, password, language = 'en', reason = nil)
75
69
  params = {
76
70
  name: username,
77
71
  password: password,
78
72
  language: language,
79
- token: token
73
+ token: get_token('createaccount')
80
74
  }
81
75
  params[:reason] = reason unless reason.nil?
82
76
 
@@ -85,15 +79,7 @@ module MediaWiki
85
79
  raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
86
80
  end
87
81
 
88
- if result['createaccount']['result'] == 'Success'
89
- @tokens.clear
90
-
91
- return true
92
- elsif result['createaccount']['result'] == 'NeedToken'
93
- return create_account(username, password, language, reason, result['createaccount']['token'])
94
- end
95
-
96
- false
82
+ result['createaccount']['result'] == 'Success'
97
83
  end
98
84
 
99
85
  # Creates an account using the random password sent by email procedure.
@@ -103,13 +89,13 @@ module MediaWiki
103
89
  # @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
104
90
  # @since 0.1.0
105
91
  # @return [Boolean] True if successful, false if not.
106
- def create_account_email(username, email, language = 'en', reason = nil, token = '')
92
+ def create_account_email(username, email, language = 'en', reason = nil)
107
93
  params = {
108
94
  name: username,
109
95
  email: email,
110
96
  mailpassword: 'value',
111
97
  language: language,
112
- token: token
98
+ token: get_token('createaccount')
113
99
  }
114
100
  params[:reason] = reason unless reason.nil?
115
101
 
@@ -118,15 +104,7 @@ module MediaWiki
118
104
  raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
119
105
  end
120
106
 
121
- if result['createaccount']['result'] == 'Success'
122
- @tokens.clear
123
-
124
- return true
125
- elsif result['createaccount']['result'] == 'NeedToken'
126
- return create_account_email(username, email, language, reason, result['createaccount']['token'])
127
- end
128
-
129
- false
107
+ result['createaccount']['result'] == 'Success'
130
108
  end
131
109
  end
132
110
  end
@@ -34,56 +34,53 @@ module MediaWiki
34
34
  # @option opts [String] :custom_agent A custom User-Agent to use. Optional.
35
35
  # @option opts [Fixnum] :query_limit_default The query limit to use if no limit parameter is explicitly given to
36
36
  # the various query methods. In other words, if you pass a limit parameter to the valid query methods, it will
37
- # use that, otherwise, it will use this. Defaults to 500. It can be set to 'max' to use MW's default max for
38
- # each API.
39
- # @option opts [Boolean] :use_continuation Whether to use the continuation API on queries.
37
+ # use that, otherwise, it will use this. Defaults to 'max' to use MW's default max for each API.
38
+ # @option opts [Boolean] :use_continuation Whether to use the continuation API on queries. Defaults to true.
40
39
  # @option opts [Symbol] :assertion If set to :user or :bot, will use the assert parameter in all requests.
41
40
  # Setting this will open up the possibility for NotLoggedInErrors and NotBotErrors. It is important to keep in
42
41
  # mind that methods that check if the user is logged in do not use the API, but check if the user has *ever*
43
42
  # logged in as this Butt instance. In other words, it is a safety check for performance and not a valid API check.
44
43
  def initialize(url, opts = {})
45
44
  @url = url =~ /api.php$/ ? url : "#{url}/api.php"
46
- @query_limit_default = opts[:query_limit_default] || 500
45
+ @query_limit_default = opts[:query_limit_default] || 'max'
47
46
  @client = HTTPClient.new
48
47
  @uri = URI.parse(@url)
49
48
  @logged_in = false
50
49
  @custom_agent = opts[:custom_agent]
51
- @use_continuation = opts[:use_continuation]
50
+ @use_continuation = opts[:use_continuation] || true
52
51
 
53
52
  assertion = opts[:assertion]
54
53
  @assertion = assertion == :user || assertion == :bot ? assertion : nil
55
54
  end
56
55
 
57
- # Performs a generic HTTP POST request and provides the response. This method generally should not be used by the
56
+ # Performs an HTTP POST request and provides the response. This method generally should not be used by the
58
57
  # user, unless there is not a helper method provided by Butt for a particular action.
59
- # @param params [Hash] A basic hash containing MediaWiki API parameters. Please see the MediaWiki API for more
60
- # information.
61
- # @param autoparse [Boolean] Whether or not to provide a parsed version of the response's JSON.
62
- # @param header [Hash] The header hash. Optional.
63
- # @param override_assertion [Boolean] Whether to override the @assertion check. This is used in #login because
64
- # that can never be done while already logged in.
58
+ # @param params [Hash] A hash containing MediaWiki API parameters. Please see the MediaWiki API for more
59
+ # information. The method automatically sets the format and assert values, unless they are specified in this
60
+ # hash argument.
65
61
  # @since 0.1.0
66
- # @return [Hash] Parsed JSON if autoparse is true.
67
- # @return [HTTPMessage] Raw HTTP response if autoparse is not true.
68
- def post(params, autoparse = true, header = nil, override_assertion = false)
69
- params[:format] = 'json'
70
- params[:assert] = @assertion.to_s if @assertion && !override_assertion && !params.key?(:assert)
71
- header = {} if header.nil?
72
-
73
- header['User-Agent'] = @logged_in ? "#{@name}/MediaWiki::Butt" : 'NotLoggedIn/MediaWiki::Butt'
74
- header['User-Agent'] = @custom_agent if defined? @custom_agent
75
-
76
- res = @client.post(@uri, params, header)
62
+ # @return [Hash] Parsed JSON returned by the MediaWiki API
63
+ def post(params)
64
+ base_params = {
65
+ format: 'json'
66
+ }
67
+ base_params[:assert] = @assertion.to_s if @assertion
68
+ params = base_params.merge(params)
69
+ header = {}
70
+ if defined? @custom_agent
71
+ header['User-Agent'] = @custom_agent
72
+ else
73
+ header['User-Agent'] = @logged_in ? "#{@name}/MediaWiki::Butt" : 'NotLoggedIn/MediaWiki::Butt'
74
+ end
77
75
 
78
- return res unless autoparse
79
- parsed = JSON.parse(res.body)
76
+ response = JSON.parse(@client.post(@uri, params, header).body)
80
77
 
81
- if !override_assertion || @assertion
82
- code = parsed.dig('error', 'code')
83
- fail MediaWiki::Butt::NotLoggedInError.new(parsed['error']['info']) if code == 'assertuserfailed'
84
- fail MediaWiki::Butt::NotBotError.new(parsed['error']['info']) if code == 'assertbotfailed'
78
+ if @assertion
79
+ code = response.dig('error', 'code')
80
+ fail MediaWiki::Butt::NotLoggedInError.new(response['error']['info']) if code == 'assertuserfailed'
81
+ fail MediaWiki::Butt::NotBotError.new(response['error']['info']) if code == 'assertbotfailed'
85
82
  end
86
- parsed
83
+ response
87
84
  end
88
85
 
89
86
  # Performs a Mediawiki API query and provides the response, dealing with continuation as necessary.
@@ -24,7 +24,7 @@ module MediaWiki
24
24
  text: text,
25
25
  nocreate: 1,
26
26
  format: 'json',
27
- token: get_token('edit', title)
27
+ token: get_token
28
28
  }
29
29
 
30
30
  params[:summary] ||= opts[:summary]
@@ -63,7 +63,7 @@ module MediaWiki
63
63
  summary: opts[:summary],
64
64
  createonly: 1,
65
65
  format: 'json',
66
- token: get_token('edit', title)
66
+ token: get_token
67
67
  }
68
68
 
69
69
  params[:bot] = '1' if opts[:bot]
@@ -90,7 +90,7 @@ module MediaWiki
90
90
  params = {
91
91
  action: 'upload',
92
92
  url: url,
93
- format: 'json'
93
+ token: get_token
94
94
  }
95
95
 
96
96
  filename = filename.nil? ? url.split('/')[-1] : filename.sub(/^File:/, '')
@@ -99,9 +99,7 @@ module MediaWiki
99
99
  allowed_extensions = get_allowed_file_extensions
100
100
  raise MediaWiki::Butt::UploadInvalidFileExtError.new unless allowed_extensions.include?(ext)
101
101
 
102
- token = get_token('edit', filename)
103
102
  params[:filename] = filename
104
- params[:token] = token
105
103
 
106
104
  response = post(params)
107
105
 
@@ -133,7 +131,7 @@ module MediaWiki
133
131
  action: 'move',
134
132
  from: from,
135
133
  to: to,
136
- token: get_token('move', from)
134
+ token: get_token
137
135
  }
138
136
 
139
137
  params[:reason] ||= opts[:reason]
@@ -158,12 +156,11 @@ module MediaWiki
158
156
  def delete(title, reason = nil)
159
157
  params = {
160
158
  action: 'delete',
161
- title: title
159
+ title: title,
160
+ token: get_token
162
161
  }
163
162
 
164
- token = get_token('delete', title)
165
163
  params[:reason] = reason unless reason.nil?
166
- params[:token] = token
167
164
 
168
165
  response = post(params)
169
166
  return true if response['delete']
@@ -8,6 +8,33 @@ module MediaWiki
8
8
  include MediaWiki::Query::Meta::UserInfo
9
9
  include MediaWiki::Query::Meta::FileRepoInfo
10
10
  include MediaWiki::Query::Meta::UserInfo
11
+
12
+ # All valid types of tokens. Taken from API:Tokens on MediaWiki.
13
+ TOKEN_TYPES = %w(csrf watch patrol rollback userrights login createaccount)
14
+
15
+ # Obtains a token for the current user (or lack thereof) for specific actions. This uses the functionality
16
+ # introduced in MediaWiki 1.27
17
+ # @param type [String, Array<String>] The type of token to get. See #TOKEN_TYPES to see the valid types. If it
18
+ # is invalid, it will default to 'csrf'. If it is an array, it will join by a pipe for the API.
19
+ # @return [String, Hash<String => String>] Either a token or a set of tokens organized by type. If multiple
20
+ # valid types are provided in the parameter, it returns a hash identical to the API response (see API docs).
21
+ def get_token(type = 'csrf')
22
+ params = {
23
+ action: 'query',
24
+ meta: 'tokens'
25
+ }
26
+
27
+ if type.is_a?(Array)
28
+ type = (type - TOKEN_TYPES).empty? ? type.join('|') : 'csrf'
29
+ else
30
+ type = TOKEN_TYPES.include?(type) ? type : 'csrf'
31
+ end
32
+ params[:type] = type
33
+
34
+ resp = post(params)
35
+ tokens = resp['query']['tokens']
36
+ tokens.size > 1 ? tokens : tokens["#{type}token"]
37
+ end
11
38
  end
12
39
  end
13
40
  end
@@ -8,35 +8,6 @@ module MediaWiki
8
8
  include MediaWiki::Query::Properties::Contributors
9
9
  include MediaWiki::Query::Properties::Pages
10
10
  include MediaWiki::Query::Properties::Files
11
-
12
- # Gets the token for the given type. This method should rarely be used by normal users.
13
- # @param type [String] The type of token.
14
- # @param title [String] The page title for the token. Optional.
15
- # @see https://www.mediawiki.org/wiki/API:Info MediaWiki Info API Docs
16
- # @since 0.5.0
17
- # @return [String] The token. If the butt isn't logged in, it returns with '+\\'.
18
- def get_token(type, title = nil)
19
- return '+\\' unless @logged_in
20
-
21
- # There is some weird thing with MediaWiki where you must pass a valid inprop parameter in order to get any
22
- # response at all. This is why there is a displaytitle inprop as well as gibberish in the titles parameter.
23
- # And to avoid normalization, it's capitalized.
24
- params = {
25
- action: 'query',
26
- prop: 'info',
27
- inprop: 'displaytitle',
28
- intoken: type
29
- }
30
-
31
- title = 'Somegibberish' if title.nil?
32
- params[:titles] = title
33
- response = post(params)
34
- revid = nil
35
- response['query']['pages'].each { |r, _| revid = r }
36
-
37
- # URL encoding is not needed for some reason.
38
- response['query']['pages'][revid]["#{type}token"]
39
- end
40
11
  end
41
12
  end
42
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mediawiki-butt
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eli Foster
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-06-22 00:00:00.000000000 Z
12
+ date: 2017-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httpclient