Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update token system to reflect latest MediaWiki #67

Merged
merged 1 commit into from
Oct 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/mediawiki/administration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def block(user, expiry = '2 weeks', reason = nil, nocreate = true)
expiry: expiry
}

token = get_token('block')
token = get_token
params[:reason] = reason if reason
params[:nocreate] = '1' if nocreate
params[:token] = token
Expand All @@ -43,7 +43,7 @@ def unblock(user, reason = nil)
action: 'unblock',
user: user
}
token = get_token('unblock')
token = get_token
params[:reason] = reason if reason
params[:token] = token

Expand Down
51 changes: 11 additions & 40 deletions lib/mediawiki/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,23 @@ module Auth
# Logs the user into the wiki. This is generally required for editing and getting restricted data.
# @param username [String] The username
# @param password [String] The password
# @param token [String] The login token to use. Only set this if you know what you are doing. You probably want
# to just let the function get the token and set it on its own.
# @see #check_login
# @see https://www.mediawiki.org/wiki/API:Login MediaWiki Login API Docs
# @since 0.1.0
# @raise [AuthenticationError]
# @return [Boolean] True if the login was successful.
def login(username, password, token = nil)
def login(username, password)
params = {
action: 'login',
lgname: username,
lgpassword: password
lgpassword: password,
lgtoken: get_token('login')
}
params[:lgtoken] = token if token
header = {}
header['Set-Cookie'] = @cookie if @cookie

response = post(params, true, header, true)
response = post(params)
result = response['login']['result']

if result == 'NeedToken'
token = response['login']['token']
return login(username, password, token)
end

if result == 'Success'
@cookie = "#{response['login']['cookieprefix']}Session=#{response['login']['sessionid']}"
@name = username
@name = response['login']['lgusername']
@logged_in = true
return true
end
Expand Down Expand Up @@ -65,18 +54,16 @@ def logout
# @param language [String] The language code to be set as default for the account. Defaults to 'en', or English.
# Use the language code, not the name.
# @param reason [String] The reason for creating the account, as shown in the account creation log. Optional.
# @param token [String] The account creation token to use. Only set this if you know what you are doing. You
# probably want to just let the function get the token and set it on its own.
# @see #check_create
# @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
# @since 0.1.0
# @return [Boolean] True if successful, false if not.
def create_account(username, password, language = 'en', reason = nil, token = '')
def create_account(username, password, language = 'en', reason = nil)
params = {
name: username,
password: password,
language: language,
token: token
token: get_token('createaccount')
}
params[:reason] = reason unless reason.nil?

Expand All @@ -85,15 +72,7 @@ def create_account(username, password, language = 'en', reason = nil, token = ''
raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
end

if result['createaccount']['result'] == 'Success'
@tokens.clear

return true
elsif result['createaccount']['result'] == 'NeedToken'
return create_account(username, password, language, reason, result['createaccount']['token'])
end

false
result['createaccount']['result'] == 'Success'
end

# Creates an account using the random password sent by email procedure.
Expand All @@ -103,13 +82,13 @@ def create_account(username, password, language = 'en', reason = nil, token = ''
# @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
# @since 0.1.0
# @return [Boolean] True if successful, false if not.
def create_account_email(username, email, language = 'en', reason = nil, token = '')
def create_account_email(username, email, language = 'en', reason = nil)
params = {
name: username,
email: email,
mailpassword: 'value',
language: language,
token: token
token: get_token('createaccount')
}
params[:reason] = reason unless reason.nil?

Expand All @@ -118,15 +97,7 @@ def create_account_email(username, email, language = 'en', reason = nil, token =
raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
end

if result['createaccount']['result'] == 'Success'
@tokens.clear

return true
elsif result['createaccount']['result'] == 'NeedToken'
return create_account_email(username, email, language, reason, result['createaccount']['token'])
end

false
result['createaccount']['result'] == 'Success'
end
end
end
15 changes: 6 additions & 9 deletions lib/mediawiki/edit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def edit(title, text, opts = {})
text: text,
nocreate: 1,
format: 'json',
token: get_token('edit', title)
token: get_token
}

params[:summary] ||= opts[:summary]
Expand Down Expand Up @@ -63,7 +63,7 @@ def create_page(title, text, opts = {})
summary: opts[:summary],
createonly: 1,
format: 'json',
token: get_token('edit', title)
token: get_token
}

params[:bot] = '1' if opts[:bot]
Expand All @@ -90,7 +90,7 @@ def upload(url, filename = nil)
params = {
action: 'upload',
url: url,
format: 'json'
token: get_token
}

filename = filename.nil? ? url.split('/')[-1] : filename.sub(/^File:/, '')
Expand All @@ -99,9 +99,7 @@ def upload(url, filename = nil)
allowed_extensions = get_allowed_file_extensions
raise MediaWiki::Butt::UploadInvalidFileExtError.new unless allowed_extensions.include?(ext)

token = get_token('edit', filename)
params[:filename] = filename
params[:token] = token

response = post(params)

Expand Down Expand Up @@ -133,7 +131,7 @@ def move(from, to, opts = {})
action: 'move',
from: from,
to: to,
token: get_token('move', from)
token: get_token
}

params[:reason] ||= opts[:reason]
Expand All @@ -158,12 +156,11 @@ def move(from, to, opts = {})
def delete(title, reason = nil)
params = {
action: 'delete',
title: title
title: title,
token: get_token
}

token = get_token('delete', title)
params[:reason] = reason unless reason.nil?
params[:token] = token

response = post(params)
return true if response['delete']
Expand Down
27 changes: 27 additions & 0 deletions lib/mediawiki/query/meta/meta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@ module Meta
include MediaWiki::Query::Meta::UserInfo
include MediaWiki::Query::Meta::FileRepoInfo
include MediaWiki::Query::Meta::UserInfo

# All valid types of tokens. Taken from API:Tokens on MediaWiki.
TOKEN_TYPES = %w(csrf watch patrol rollback userrights login createaccount)

# Obtains a token for the current user (or lack thereof) for specific actions. This uses the functionality
# introduced in MediaWiki 1.27
# @param type [String, Array<String>] The type of token to get. See #TOKEN_TYPES to see the valid types. If it
# is invalid, it will default to 'csrf'. If it is an array, it will join by a pipe for the API.
# @return [String, Hash<String => String>] Either a token or a set of tokens organized by type. If multiple
# valid types are provided in the parameter, it returns a hash identical to the API response (see API docs).
def get_token(type = 'csrf')
params = {
action: 'query',
meta: 'tokens'
}

if type.is_a?(Array)
type = (type - TOKEN_TYPES).empty? ? type.join('|') : 'csrf'
else
type = TOKEN_TYPES.include?(type) ? type : 'csrf'
end
params[:type] = type

resp = post(params)
tokens = resp['query']['tokens']
tokens.size > 1 ? tokens : tokens["#{type}token"]
end
end
end
end
29 changes: 0 additions & 29 deletions lib/mediawiki/query/properties/properties.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,6 @@ module Properties
include MediaWiki::Query::Properties::Contributors
include MediaWiki::Query::Properties::Pages
include MediaWiki::Query::Properties::Files

# Gets the token for the given type. This method should rarely be used by normal users.
# @param type [String] The type of token.
# @param title [String] The page title for the token. Optional.
# @see https://www.mediawiki.org/wiki/API:Info MediaWiki Info API Docs
# @since 0.5.0
# @return [String] The token. If the butt isn't logged in, it returns with '+\\'.
def get_token(type, title = nil)
return '+\\' unless @logged_in

# There is some weird thing with MediaWiki where you must pass a valid inprop parameter in order to get any
# response at all. This is why there is a displaytitle inprop as well as gibberish in the titles parameter.
# And to avoid normalization, it's capitalized.
params = {
action: 'query',
prop: 'info',
inprop: 'displaytitle',
intoken: type
}

title = 'Somegibberish' if title.nil?
params[:titles] = title
response = post(params)
revid = nil
response['query']['pages'].each { |r, _| revid = r }

# URL encoding is not needed for some reason.
response['query']['pages'][revid]["#{type}token"]
end
end
end
end