Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33101651
remote_follow_controller_test.exs
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
remote_follow_controller_test.exs
View Options
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule
Pleroma.Web.TwitterAPI.RemoteFollowControllerTest
do
use
Pleroma.Web.ConnCase
alias
Pleroma.MFA
alias
Pleroma.MFA.TOTP
alias
Pleroma.UnstubbedConfigMock
,
as
:
ConfigMock
alias
Pleroma.User
alias
Pleroma.Web.CommonAPI
import
Ecto.Query
import
ExUnit.CaptureLog
import
Mox
import
Pleroma.Factory
setup_all
do
:
clear_config
([
:instance
,
:federating
],
true
)
setup
do
:
clear_config
([
:user
,
:deny_follow_blocked
])
describe
"GET /ostatus_subscribe - remote_follow/2"
do
test
"adds status to pleroma instance if the `acct` is a status"
,
%{
conn
:
conn
}
do
Tesla.Mock
.
mock
(
fn
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie/statuses/101849165031453009"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/tesla_mock/status.emelie.json"
)
}
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie/collections/featured"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/users_mock/masto_featured.json"
)
|>
String
.
replace
(
"{{domain}}"
,
"mastodon.social"
)
|>
String
.
replace
(
"{{nickname}}"
,
"emelie"
)
}
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/tesla_mock/emelie.json"
)
}
end
)
assert
conn
|>
get
(
remote_follow_path
(
conn
,
:follow
,
%{
acct
:
"https://mastodon.social/users/emelie/statuses/101849165031453009"
})
)
|>
redirected_to
()
=~
"/notice/"
end
test
"show follow account page if the `acct` is a account link"
,
%{
conn
:
conn
}
do
Tesla.Mock
.
mock
(
fn
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/tesla_mock/emelie.json"
)
}
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie/collections/featured"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/users_mock/masto_featured.json"
)
|>
String
.
replace
(
"{{domain}}"
,
"mastodon.social"
)
|>
String
.
replace
(
"{{nickname}}"
,
"emelie"
)
}
end
)
response
=
conn
|>
get
(
remote_follow_path
(
conn
,
:follow
,
%{
acct
:
"https://mastodon.social/users/emelie"
}))
|>
html_response
(
200
)
assert
response
=~
"Log in to follow"
end
test
"show follow page if the `acct` is a account link"
,
%{
conn
:
conn
}
do
Tesla.Mock
.
mock
(
fn
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/tesla_mock/emelie.json"
)
}
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie/collections/featured"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/users_mock/masto_featured.json"
)
|>
String
.
replace
(
"{{domain}}"
,
"mastodon.social"
)
|>
String
.
replace
(
"{{nickname}}"
,
"emelie"
)
}
end
)
user
=
insert
(
:user
)
response
=
conn
|>
assign
(
:user
,
user
)
|>
get
(
remote_follow_path
(
conn
,
:follow
,
%{
acct
:
"https://mastodon.social/users/emelie"
}))
|>
html_response
(
200
)
assert
response
=~
"Remote follow"
end
test
"show follow page with error when user can not be fetched by `acct` link"
,
%{
conn
:
conn
}
do
Tesla.Mock
.
mock
(
fn
%{
method
:
:get
,
url
:
"https://mastodon.social/users/not_found"
}
->
%
Tesla.Env
{
status
:
404
}
end
)
user
=
insert
(
:user
)
assert
capture_log
(
fn
->
response
=
conn
|>
assign
(
:user
,
user
)
|>
get
(
remote_follow_path
(
conn
,
:follow
,
%{
acct
:
"https://mastodon.social/users/not_found"
})
)
|>
html_response
(
200
)
assert
response
=~
"Error fetching user"
end
)
=~
":not_found"
end
end
describe
"POST /ostatus_subscribe - do_follow/2 with assigned user "
do
test
"required `follow | write:follows` scope"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
read_token
=
insert
(
:oauth_token
,
user
:
user
,
scopes
:
[
"read"
])
assert
capture_log
(
fn
->
response
=
conn
|>
assign
(
:user
,
user
)
|>
assign
(
:token
,
read_token
)
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
user2
.
id
}})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
)
=~
"Insufficient permissions: follow | write:follows."
end
test
"follows user"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
conn
=
conn
|>
assign
(
:user
,
user
)
|>
assign
(
:token
,
insert
(
:oauth_token
,
user
:
user
,
scopes
:
[
"write:follows"
]))
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
user2
.
id
}})
assert
redirected_to
(
conn
)
==
"/users/
#{
user2
.
id
}
"
end
test
"returns error when user is deactivated"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
,
is_active
:
false
)
user2
=
insert
(
:user
)
response
=
conn
|>
assign
(
:user
,
user
)
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
user2
.
id
}})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
test
"returns error when user is blocked"
,
%{
conn
:
conn
}
do
clear_config
([
:user
,
:deny_follow_blocked
],
true
)
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
{
:ok
,
_user_block
}
=
Pleroma.User
.
block
(
user2
,
user
)
response
=
conn
|>
assign
(
:user
,
user
)
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
user2
.
id
}})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
test
"returns error when followee not found"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
response
=
conn
|>
assign
(
:user
,
user
)
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
"jimm"
}})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
test
"returns success result when user already in followers"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
{
:ok
,
_
,
_
,
_
}
=
CommonAPI
.
follow
(
user2
,
user
)
conn
=
conn
|>
assign
(
:user
,
refresh_record
(
user
))
|>
assign
(
:token
,
insert
(
:oauth_token
,
user
:
user
,
scopes
:
[
"write:follows"
]))
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"user"
=>
%{
"id"
=>
user2
.
id
}})
assert
redirected_to
(
conn
)
==
"/users/
#{
user2
.
id
}
"
end
end
describe
"POST /ostatus_subscribe - follow/2 with enabled Two-Factor Auth "
do
test
"render the MFA login form"
,
%{
conn
:
conn
}
do
otp_secret
=
TOTP
.
generate_secret
()
user
=
insert
(
:user
,
multi_factor_authentication_settings
:
%
MFA.Settings
{
enabled
:
true
,
totp
:
%
MFA.Settings.TOTP
{
secret
:
otp_secret
,
confirmed
:
true
}
}
)
user2
=
insert
(
:user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"test"
,
"id"
=>
user2
.
id
}
})
|>
response
(
200
)
mfa_token
=
Pleroma.Repo
.
one
(
from
(
q
in
Pleroma.MFA.Token
,
where
:
q
.
user_id
==
^
user
.
id
))
assert
response
=~
"Two-factor authentication"
assert
response
=~
"Authentication code"
assert
response
=~
mfa_token
.
token
refute
user2
.
follower_address
in
User
.
following
(
user
)
end
test
"returns error when password is incorrect"
,
%{
conn
:
conn
}
do
otp_secret
=
TOTP
.
generate_secret
()
user
=
insert
(
:user
,
multi_factor_authentication_settings
:
%
MFA.Settings
{
enabled
:
true
,
totp
:
%
MFA.Settings.TOTP
{
secret
:
otp_secret
,
confirmed
:
true
}
}
)
user2
=
insert
(
:user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"test1"
,
"id"
=>
user2
.
id
}
})
|>
response
(
200
)
assert
response
=~
"Wrong username or password"
refute
user2
.
follower_address
in
User
.
following
(
user
)
end
test
"follows"
,
%{
conn
:
conn
}
do
otp_secret
=
TOTP
.
generate_secret
()
user
=
insert
(
:user
,
multi_factor_authentication_settings
:
%
MFA.Settings
{
enabled
:
true
,
totp
:
%
MFA.Settings.TOTP
{
secret
:
otp_secret
,
confirmed
:
true
}
}
)
{
:ok
,
%{
token
:
token
}}
=
MFA.Token
.
create
(
user
)
user2
=
insert
(
:user
)
otp_token
=
TOTP
.
generate_token
(
otp_secret
)
conn
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"mfa"
=>
%{
"code"
=>
otp_token
,
"token"
=>
token
,
"id"
=>
user2
.
id
}
}
)
assert
redirected_to
(
conn
)
==
"/users/
#{
user2
.
id
}
"
assert
user2
.
follower_address
in
User
.
following
(
user
)
end
test
"returns error when auth code is incorrect"
,
%{
conn
:
conn
}
do
otp_secret
=
TOTP
.
generate_secret
()
user
=
insert
(
:user
,
multi_factor_authentication_settings
:
%
MFA.Settings
{
enabled
:
true
,
totp
:
%
MFA.Settings.TOTP
{
secret
:
otp_secret
,
confirmed
:
true
}
}
)
{
:ok
,
%{
token
:
token
}}
=
MFA.Token
.
create
(
user
)
user2
=
insert
(
:user
)
otp_token
=
TOTP
.
generate_token
(
TOTP
.
generate_secret
())
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"mfa"
=>
%{
"code"
=>
otp_token
,
"token"
=>
token
,
"id"
=>
user2
.
id
}
}
)
|>
response
(
200
)
assert
response
=~
"Wrong authentication code"
refute
user2
.
follower_address
in
User
.
following
(
user
)
end
end
describe
"POST /ostatus_subscribe - follow/2 without assigned user "
do
test
"follows"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
conn
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"test"
,
"id"
=>
user2
.
id
}
})
assert
redirected_to
(
conn
)
==
"/users/
#{
user2
.
id
}
"
assert
user2
.
follower_address
in
User
.
following
(
user
)
end
test
"returns error when followee not found"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"test"
,
"id"
=>
"jimm"
}
})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
test
"returns error when login invalid"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
"jimm"
,
"password"
=>
"test"
,
"id"
=>
user
.
id
}
})
|>
response
(
200
)
assert
response
=~
"Wrong username or password"
end
test
"returns error when password invalid"
,
%{
conn
:
conn
}
do
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"42"
,
"id"
=>
user2
.
id
}
})
|>
response
(
200
)
assert
response
=~
"Wrong username or password"
end
test
"returns error when user is blocked"
,
%{
conn
:
conn
}
do
clear_config
([
:user
,
:deny_follow_blocked
],
true
)
user
=
insert
(
:user
)
user2
=
insert
(
:user
)
{
:ok
,
_user_block
}
=
Pleroma.User
.
block
(
user2
,
user
)
response
=
conn
|>
post
(
remote_follow_path
(
conn
,
:do_follow
),
%{
"authorization"
=>
%{
"name"
=>
user
.
nickname
,
"password"
=>
"test"
,
"id"
=>
user2
.
id
}
})
|>
response
(
200
)
assert
response
=~
"Error following account"
end
end
describe
"avatar url"
do
test
"without media proxy"
do
clear_config
([
:media_proxy
,
:enabled
],
false
)
user
=
insert
(
:user
,
%{
local
:
false
,
avatar
:
%{
"url"
=>
[%{
"href"
=>
"https://remote.org/avatar.png"
}]}
})
avatar_url
=
Pleroma.Web.TwitterAPI.RemoteFollowView
.
avatar_url
(
user
)
assert
avatar_url
==
"https://remote.org/avatar.png"
end
test
"with media proxy"
do
clear_config
([
:media_proxy
,
:enabled
],
true
)
ConfigMock
|>
stub_with
(
Pleroma.Test.StaticConfig
)
user
=
insert
(
:user
,
%{
local
:
false
,
avatar
:
%{
"url"
=>
[%{
"href"
=>
"https://remote.org/avatar.png"
}]}
})
avatar_url
=
Pleroma.Web.TwitterAPI.RemoteFollowView
.
avatar_url
(
user
)
url
=
Pleroma.Web.Endpoint
.
url
()
assert
String
.
starts_with?
(
avatar_url
,
url
)
end
test
"local avatar is not proxied"
do
clear_config
([
:media_proxy
,
:enabled
],
true
)
user
=
insert
(
:user
,
%{
local
:
true
,
avatar
:
%{
"url"
=>
[%{
"href"
=>
"
#{
Pleroma.Web.Endpoint
.
url
()
}
/localuser/avatar.png"
}]}
})
avatar_url
=
Pleroma.Web.TwitterAPI.RemoteFollowView
.
avatar_url
(
user
)
assert
avatar_url
==
"
#{
Pleroma.Web.Endpoint
.
url
()
}
/localuser/avatar.png"
end
end
describe
"GET /authorize_interaction - authorize_interaction/2"
do
test
"redirects to /ostatus_subscribe"
,
%{
conn
:
conn
}
do
Tesla.Mock
.
mock
(
fn
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/tesla_mock/emelie.json"
)
}
%{
method
:
:get
,
url
:
"https://mastodon.social/users/emelie/collections/featured"
}
->
%
Tesla.Env
{
status
:
200
,
headers
:
[{
"content-type"
,
"application/activity+json"
}],
body
:
File
.
read!
(
"test/fixtures/users_mock/masto_featured.json"
)
|>
String
.
replace
(
"{{domain}}"
,
"mastodon.social"
)
|>
String
.
replace
(
"{{nickname}}"
,
"emelie"
)
}
end
)
conn
=
conn
|>
get
(
remote_follow_path
(
conn
,
:authorize_interaction
,
%{
uri
:
"https://mastodon.social/users/emelie"
})
)
assert
redirected_to
(
conn
)
==
remote_follow_path
(
conn
,
:follow
,
%{
acct
:
"https://mastodon.social/users/emelie"
})
end
end
end
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 20, 12:43 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
931559
Default Alt Text
remote_follow_controller_test.exs (15 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment