Add ability to use remote follow function on other sites

feature/8296-invite_api
Eugen Rochko 6 years ago
parent 8b94d283fb
commit d7dc84439c
  1. 58
      app/assets/stylesheets/accounts.scss
  2. 11
      app/assets/stylesheets/application.scss
  3. 2
      app/assets/stylesheets/forms.scss
  4. 24
      app/controllers/authorize_follow_controller.rb
  5. 2
      app/helpers/authorize_follow_helper.rb
  6. 2
      app/views/accounts/_grid_card.html.haml
  7. 3
      app/views/authorize_follow/error.html.haml
  8. 21
      app/views/authorize_follow/new.html.haml
  9. 5
      app/views/oauth/authorizations/error.html.haml
  10. 39
      app/views/oauth/authorizations/new.html.haml
  11. 5
      app/views/oauth/authorizations/show.html.haml
  12. 3
      app/views/xrd/webfinger.json.rabl
  13. 1
      app/views/xrd/webfinger.xml.ruby
  14. 2
      config/application.rb
  15. 5
      config/locales/en.yml
  16. 4
      config/routes.rb
  17. 6
      spec/controllers/authorize_follow_controller_spec.rb
  18. 5
      spec/helpers/authorize_follow_helper_spec.rb

@ -324,3 +324,61 @@
padding-bottom: 25px;
cursor: default;
}
.account-card {
padding: 14px 10px;
background: #fff;
border-radius: 4px;
text-align: left;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
.detailed-status__display-name {
display: block;
overflow: hidden;
margin-bottom: 15px;
& > div {
float: left;
margin-right: 10px;
width: 48px;
height: 48px;
}
.avatar {
display: block;
border-radius: 4px;
}
.display-name {
display: block;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: default;
strong {
font-weight: 500;
color: #282c37;
}
span {
font-size: 14px;
color: #9baec8;
}
}
&:hover {
.display-name {
strong {
text-decoration: none;
}
}
}
}
.account__header__content {
font-size: 14px;
color: #282c37;
}
}

@ -214,11 +214,13 @@ body {
.footer {
text-align: center;
margin-top: 30px;
font-size: 12px;
color: darken(#d9e1e8, 25%);
.domain {
font-size: 12px;
font-weight: 400;
font-family: 'Roboto Mono', monospace;
//font-size: 12px;
font-weight: 500;
//font-family: 'Roboto Mono', monospace;
a {
color: inherit;
@ -227,13 +229,12 @@ body {
}
.powered-by {
font-size: 12px;
font-weight: 400;
color: darken(#d9e1e8, 25%);
a {
color: inherit;
text-decoration: underline;
font-weight: 500;
&:hover {
text-decoration: none;

@ -185,7 +185,7 @@ code {
}
}
.oauth-prompt {
.oauth-prompt, .follow-prompt {
margin-bottom: 30px;
text-align: center;
color: #9baec8;

@ -0,0 +1,24 @@
# frozen_string_literal: true
class AuthorizeFollowController < ApplicationController
layout 'public'
before_action :authenticate_user!
def new
@account = FollowRemoteAccountService.new.call(params[:acct])
render :error if @account.nil?
end
def create
@account = FollowService.new.call(current_account, params[:acct]).try(:target_account)
if @account.nil?
render :error
else
redirect_to web_url("accounts/#{@account.id}")
end
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermitted
render :error
end
end

@ -0,0 +1,2 @@
module AuthorizeFollowHelper
end

@ -1,6 +1,6 @@
.account-grid-card
.account-grid-card__header
.avatar= image_tag account.avatar.url( :original)
.avatar= image_tag account.avatar.url(:original)
.name
= link_to TagManager.instance.url_for(account) do
%span.display_name= display_name(account)

@ -0,0 +1,3 @@
.form-container
.flash-message#error_explanation
= t('authorize_follow.error')

@ -0,0 +1,21 @@
- content_for :page_title do
= t('authorize_follow.title', acct: @account.acct)
.form-container
.follow-prompt
%h2= t('authorize_follow.prompt_html', self: current_account.username)
.account-card
.detailed-status__display-name
%div
= image_tag @account.avatar.url(:original), alt: '', width: 48, height: 48, class: 'avatar'
%span.display-name
%strong= display_name(@account)
%span= "@#{@account.acct}"
.account__header__content= Formatter.instance.simplified_format(@account)
= form_tag authorize_follow_path, method: :post, class: 'simple_form' do
= hidden_field_tag :acct, @account.acct
= button_tag t('authorize_follow.follow'), type: :submit

@ -1,2 +1,3 @@
.flash-message#error_explanation
= @pre_auth.error_response.body[:error_description]
.form-container
.flash-message#error_explanation
= @pre_auth.error_response.body[:error_description]

@ -1,25 +1,26 @@
- content_for :page_title do
= t('doorkeeper.authorizations.new.title')
.oauth-prompt
%h2= t('doorkeeper.authorizations.new.prompt', client_name: @pre_auth.client.name)
.form-container
.oauth-prompt
%h2= t('doorkeeper.authorizations.new.prompt', client_name: @pre_auth.client.name)
%p
= t('doorkeeper.authorizations.new.able_to')
= @pre_auth.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.map { |s| "<strong>#{s}</strong>"}.to_sentence.html_safe
%p
= t('doorkeeper.authorizations.new.able_to')
= @pre_auth.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.map { |s| "<strong>#{s}</strong>"}.to_sentence.html_safe
= form_tag oauth_authorization_path, method: :post, class: 'simple_form' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
= hidden_field_tag :state, @pre_auth.state
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= button_tag t('doorkeeper.authorizations.buttons.authorize'), type: :submit
= form_tag oauth_authorization_path, method: :post, class: 'simple_form' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
= hidden_field_tag :state, @pre_auth.state
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= button_tag t('doorkeeper.authorizations.buttons.authorize'), type: :submit
= form_tag oauth_authorization_path, method: :delete, class: 'simple_form' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
= hidden_field_tag :state, @pre_auth.state
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= button_tag t('doorkeeper.authorizations.buttons.deny'), type: :submit, class: 'negative'
= form_tag oauth_authorization_path, method: :delete, class: 'simple_form' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
= hidden_field_tag :state, @pre_auth.state
= hidden_field_tag :response_type, @pre_auth.response_type
= hidden_field_tag :scope, @pre_auth.scope
= button_tag t('doorkeeper.authorizations.buttons.deny'), type: :submit, class: 'negative'

@ -1,2 +1,3 @@
.flash-message
%code= params[:code]
.form-container
.flash-message
%code= params[:code]

@ -11,6 +11,7 @@ node(:links) do
{ rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: TagManager.instance.url_for(@account) },
{ rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom') },
{ rel: 'salmon', href: api_salmon_url(@account.id) },
{ rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}" }
{ rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}" },
{ rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}" },
]
end

@ -6,5 +6,6 @@ Nokogiri::XML::Builder.new do |xml|
xml.Link(rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(@account, format: 'atom'))
xml.Link(rel: 'salmon', href: api_salmon_url(@account.id))
xml.Link(rel: 'magic-public-key', href: "data:application/magic-public-key,#{@magic_key}")
xml.Link(rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_follow_url}?acct={uri}")
end
end.to_xml

@ -45,7 +45,7 @@ module Mastodon
config.browserify_rails.commandline_options = '--transform [ babelify --presets [ es2015 react ] ] --extension=".jsx"'
config.to_prepare do
Doorkeeper::AuthorizationsController.layout 'auth'
Doorkeeper::AuthorizationsController.layout 'public'
end
config.action_dispatch.default_headers = {

@ -26,6 +26,11 @@ en:
resend_confirmation: Resend confirmation instructions
reset_password: Reset password
set_new_password: Set new password
authorize_follow:
error: Unfortunately, there was an error looking up the remote account
follow: Follow
prompt_html: 'You (<strong>%{self}</strong>) have requested to follow:'
title: Follow %{acct}
datetime:
distance_in_words:
about_x_hours: "%{count}h"

@ -48,6 +48,10 @@ Rails.application.routes.draw do
resources :media, only: [:show]
resources :tags, only: [:show]
# Remote follow
get :authorize_follow, to: 'authorize_follow#new'
post :authorize_follow, to: 'authorize_follow#create'
namespace :admin do
resources :pubsubhubbub, only: [:index]
resources :domain_blocks, only: [:index, :create]

@ -0,0 +1,6 @@
require 'rails_helper'
RSpec.describe AuthorizeFollowController, type: :controller do
describe 'GET #new'
describe 'POST #create'
end

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe AuthorizeFollowHelper, type: :helper do
end
Loading…
Cancel
Save