about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-12-29 16:54:54 +0100
committerEugen Rochko <eugen@zeonfederated.com>2016-12-29 16:54:54 +0100
commitd7dc84439c60069a0cb9eeca81dc61c297a8667b (patch)
tree167ee6db4fdc7008e2e517a0e983edb9721f4a7a
parent8b94d283fb45f054ee5193b0cec8586461d636b1 (diff)
Add ability to use remote follow function on other sites
-rw-r--r--app/assets/stylesheets/accounts.scss58
-rw-r--r--app/assets/stylesheets/application.scss11
-rw-r--r--app/assets/stylesheets/forms.scss2
-rw-r--r--app/controllers/authorize_follow_controller.rb24
-rw-r--r--app/helpers/authorize_follow_helper.rb2
-rw-r--r--app/views/accounts/_grid_card.html.haml2
-rw-r--r--app/views/authorize_follow/error.html.haml3
-rw-r--r--app/views/authorize_follow/new.html.haml21
-rw-r--r--app/views/oauth/authorizations/error.html.haml5
-rw-r--r--app/views/oauth/authorizations/new.html.haml39
-rw-r--r--app/views/oauth/authorizations/show.html.haml5
-rw-r--r--app/views/xrd/webfinger.json.rabl3
-rw-r--r--app/views/xrd/webfinger.xml.ruby1
-rw-r--r--config/application.rb2
-rw-r--r--config/locales/en.yml5
-rw-r--r--config/routes.rb4
-rw-r--r--spec/controllers/authorize_follow_controller_spec.rb6
-rw-r--r--spec/helpers/authorize_follow_helper_spec.rb5
18 files changed, 166 insertions, 32 deletions
diff --git a/app/assets/stylesheets/accounts.scss b/app/assets/stylesheets/accounts.scss
index 7f33f178d..5d0963307 100644
--- a/app/assets/stylesheets/accounts.scss
+++ b/app/assets/stylesheets/accounts.scss
@@ -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;
+  }
+}
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index d05ca3795..e4c550b81 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -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;
diff --git a/app/assets/stylesheets/forms.scss b/app/assets/stylesheets/forms.scss
index cf9b4fba6..e6d2e85a2 100644
--- a/app/assets/stylesheets/forms.scss
+++ b/app/assets/stylesheets/forms.scss
@@ -185,7 +185,7 @@ code {
   }
 }
 
-.oauth-prompt {
+.oauth-prompt, .follow-prompt {
   margin-bottom: 30px;
   text-align: center;
   color: #9baec8;
diff --git a/app/controllers/authorize_follow_controller.rb b/app/controllers/authorize_follow_controller.rb
new file mode 100644
index 000000000..a276250a4
--- /dev/null
+++ b/app/controllers/authorize_follow_controller.rb
@@ -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
diff --git a/app/helpers/authorize_follow_helper.rb b/app/helpers/authorize_follow_helper.rb
new file mode 100644
index 000000000..43659ccfa
--- /dev/null
+++ b/app/helpers/authorize_follow_helper.rb
@@ -0,0 +1,2 @@
+module AuthorizeFollowHelper
+end
diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml
index dfd7a9f5e..dfdb23161 100644
--- a/app/views/accounts/_grid_card.html.haml
+++ b/app/views/accounts/_grid_card.html.haml
@@ -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)
diff --git a/app/views/authorize_follow/error.html.haml b/app/views/authorize_follow/error.html.haml
new file mode 100644
index 000000000..88d33b68d
--- /dev/null
+++ b/app/views/authorize_follow/error.html.haml
@@ -0,0 +1,3 @@
+.form-container
+  .flash-message#error_explanation
+    = t('authorize_follow.error')
diff --git a/app/views/authorize_follow/new.html.haml b/app/views/authorize_follow/new.html.haml
new file mode 100644
index 000000000..7368b834a
--- /dev/null
+++ b/app/views/authorize_follow/new.html.haml
@@ -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
diff --git a/app/views/oauth/authorizations/error.html.haml b/app/views/oauth/authorizations/error.html.haml
index ee72d9740..408ca2b86 100644
--- a/app/views/oauth/authorizations/error.html.haml
+++ b/app/views/oauth/authorizations/error.html.haml
@@ -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]
diff --git a/app/views/oauth/authorizations/new.html.haml b/app/views/oauth/authorizations/new.html.haml
index f058e2cce..1f951c272 100644
--- a/app/views/oauth/authorizations/new.html.haml
+++ b/app/views/oauth/authorizations/new.html.haml
@@ -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'
diff --git a/app/views/oauth/authorizations/show.html.haml b/app/views/oauth/authorizations/show.html.haml
index 897a15cee..b56667f35 100644
--- a/app/views/oauth/authorizations/show.html.haml
+++ b/app/views/oauth/authorizations/show.html.haml
@@ -1,2 +1,3 @@
-.flash-message
-  %code= params[:code]
+.form-container
+  .flash-message
+    %code= params[:code]
diff --git a/app/views/xrd/webfinger.json.rabl b/app/views/xrd/webfinger.json.rabl
index 0de17ac19..e637ed9d3 100644
--- a/app/views/xrd/webfinger.json.rabl
+++ b/app/views/xrd/webfinger.json.rabl
@@ -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
diff --git a/app/views/xrd/webfinger.xml.ruby b/app/views/xrd/webfinger.xml.ruby
index ee5b5fc9d..80ac71d27 100644
--- a/app/views/xrd/webfinger.xml.ruby
+++ b/app/views/xrd/webfinger.xml.ruby
@@ -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
diff --git a/config/application.rb b/config/application.rb
index 091f9c535..79ace8521 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -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 = {
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 760078862..f57c72026 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -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"
diff --git a/config/routes.rb b/config/routes.rb
index 985d6583d..1468d426b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -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]
diff --git a/spec/controllers/authorize_follow_controller_spec.rb b/spec/controllers/authorize_follow_controller_spec.rb
new file mode 100644
index 000000000..954efd53e
--- /dev/null
+++ b/spec/controllers/authorize_follow_controller_spec.rb
@@ -0,0 +1,6 @@
+require 'rails_helper'
+
+RSpec.describe AuthorizeFollowController, type: :controller do
+  describe 'GET #new'
+  describe 'POST #create'
+end
diff --git a/spec/helpers/authorize_follow_helper_spec.rb b/spec/helpers/authorize_follow_helper_spec.rb
new file mode 100644
index 000000000..ba5b0a70b
--- /dev/null
+++ b/spec/helpers/authorize_follow_helper_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe AuthorizeFollowHelper, type: :helper do
+
+end