Adding doorkeeper, adding a REST API

POST /api/statuses                  Params: status (text contents), in_reply_to_id (optional)
GET  /api/statuses/:id
POST /api/statuses/:id/reblog

GET  /api/accounts/:id
GET  /api/accounts/:id/following
GET  /api/accounts/:id/followers
POST /api/accounts/:id/follow
POST /api/accounts/:id/unfollow

POST /api/follows                  Params: uri (e.g. user@domain)

OAuth authentication is currently disabled, but the API can be used with HTTP Auth.
This commit is contained in:
Eugen Rochko
2016-03-07 12:42:33 +01:00
parent 3824c58853
commit ab6696e855
54 changed files with 847 additions and 61 deletions

View File

@ -0,0 +1,2 @@
collection @followers
extends('api/accounts/show')

View File

@ -0,0 +1,2 @@
collection @following
extends('api/accounts/show')

View File

@ -0,0 +1,9 @@
object @account
attributes :id, :username, :acct, :display_name, :note
node(:url) { |account| url_for_target(account) }
node(:avatar) { |account| asset_url(account.avatar.url(:large, false)) }
node(:followers) { |account| account.followers.count }
node(:following) { |account| account.following.count }
node(:statuses) { |account| account.statuses.count }

View File

@ -0,0 +1,2 @@
collection @statuses
extends('api/statuses/show')

View File

@ -0,0 +1,5 @@
object @follow
child :target_account => :target_account do
extends('api/accounts/show')
end

View File

@ -0,0 +1,18 @@
object @status
attributes :id, :created_at, :in_reply_to_id
node(:uri) { |status| uri_for_target(status) }
node(:content) { |status| status.local? ? linkify(status) : status.content }
node(:url) { |status| url_for_target(status) }
node(:reblogs) { |status| status.reblogs.count }
node(:favourites) { |status| status.favourites.count }
node(:favourited) { |status| current_user.account.favourited?(status) }
node(:reblogged) { |status| current_user.account.reblogged?(status) }
child :reblog => :reblog do
extends('api/statuses/show')
end
child :account do
extends('api/accounts/show')
end

View File

@ -0,0 +1,5 @@
<%- submit_btn_css ||= 'btn btn-link' %>
<%= form_tag oauth_application_path(application) do %>
<input type="hidden" name="_method" value="delete">
<%= submit_tag t('doorkeeper.applications.buttons.destroy'), onclick: "return confirm('#{ t('doorkeeper.applications.confirmations.destroy') }')", class: submit_btn_css %>
<% end %>

View File

@ -0,0 +1,47 @@
<%= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f| %>
<% if application.errors.any? %>
<div class="alert alert-danger" data-alert><p><%= t('doorkeeper.applications.form.error') %></p></div>
<% end %>
<%= content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do %>
<%= f.label :name, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_field :name, class: 'form-control' %>
<%= doorkeeper_errors_for application, :name %>
</div>
<% end %>
<%= content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do %>
<%= f.label :redirect_uri, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_area :redirect_uri, class: 'form-control' %>
<%= doorkeeper_errors_for application, :redirect_uri %>
<span class="help-block">
<%= t('doorkeeper.applications.help.redirect_uri') %>
</span>
<% if Doorkeeper.configuration.native_redirect_uri %>
<span class="help-block">
<%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: "<code>#{ Doorkeeper.configuration.native_redirect_uri }</code>") %>
</span>
<% end %>
</div>
<% end %>
<%= content_tag :div, class: "form-group#{' has-error' if application.errors[:scopes].present?}" do %>
<%= f.label :scopes, class: 'col-sm-2 control-label' %>
<div class="col-sm-10">
<%= f.text_field :scopes, class: 'form-control' %>
<%= doorkeeper_errors_for application, :scopes %>
<span class="help-block">
<%= t('doorkeeper.applications.help.scopes') %>
</span>
</div>
<% end %>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<%= f.submit t('doorkeeper.applications.buttons.submit'), class: "btn btn-primary" %>
<%= link_to t('doorkeeper.applications.buttons.cancel'), oauth_applications_path, :class => "btn btn-default" %>
</div>
</div>
<% end %>

View File

@ -0,0 +1,5 @@
<div class="page-header">
<h1><%= t('.title') %></h1>
</div>
<%= render 'form', application: @application %>

View File

@ -0,0 +1,26 @@
<div class="page-header">
<h1><%= t('.title') %></h1>
</div>
<p><%= link_to t('.new'), new_oauth_application_path, class: 'btn btn-success' %></p>
<table class="table table-striped">
<thead>
<tr>
<th><%= t('.name') %></th>
<th><%= t('.callback_url') %></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @applications.each do |application| %>
<tr id="application_<%= application.id %>">
<td><%= link_to application.name, oauth_application_path(application) %></td>
<td><%= application.redirect_uri %></td>
<td><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td>
<td><%= render 'delete_form', application: application %></td>
</tr>
<% end %>
</tbody>
</table>

View File

@ -0,0 +1,5 @@
<div class="page-header">
<h1><%= t('.title') %></h1>
</div>
<%= render 'form', application: @application %>

View File

@ -0,0 +1,39 @@
<div class="page-header">
<h1><%= t('.title', name: @application.name) %></h1>
</div>
<div class="row">
<div class="col-md-8">
<h4><%= t('.application_id') %>:</h4>
<p><code id="application_id"><%= @application.uid %></code></p>
<h4><%= t('.secret') %>:</h4>
<p><code id="secret"><%= @application.secret %></code></p>
<h4><%= t('.scopes') %>:</h4>
<p><code id="scopes"><%= @application.scopes %></code></p>
<h4><%= t('.callback_urls') %>:</h4>
<table>
<% @application.redirect_uri.split.each do |uri| %>
<tr>
<td>
<code><%= uri %></code>
</td>
<td>
<%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code'), class: 'btn btn-success', target: '_blank' %>
</td>
</tr>
<% end %>
</table>
</div>
<div class="col-md-4">
<h3><%= t('.actions') %></h3>
<p><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(@application), class: 'btn btn-primary' %></p>
<p><%= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger' %></p>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div class="page-header">
<h1><%= t('doorkeeper.authorizations.error.title') %></h1>
</div>
<main role="main">
<pre><%= @pre_auth.error_response.body[:error_description] %></pre>
</main>

View File

@ -0,0 +1,40 @@
<header class="page-header" role="banner">
<h1><%= t('.title') %></h1>
</header>
<main role="main">
<p class="h4">
<%= raw t('.prompt', client_name: "<strong class=\"text-info\">#{ @pre_auth.client.name }</strong>") %>
</p>
<% if @pre_auth.scopes.count > 0 %>
<div id="oauth-permissions">
<p><%= t('.able_to') %>:</p>
<ul class="text-info">
<% @pre_auth.scopes.each do |scope| %>
<li><%= t scope, scope: [:doorkeeper, :scopes] %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form_tag oauth_authorization_path, method: :post 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 %>
<%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success btn-lg btn-block" %>
<% end %>
<%= form_tag oauth_authorization_path, method: :delete 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 %>
<%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger btn-lg btn-block" %>
<% end %>
</div>
</main>

View File

@ -0,0 +1,7 @@
<header class="page-header">
<h1><%= t('.title') %>:</h1>
</header>
<main role="main">
<code id="authorization_code"><%= params[:code] %></code>
</main>

View File

@ -0,0 +1,5 @@
<%- submit_btn_css ||= 'btn btn-link' %>
<%= form_tag oauth_authorized_application_path(application) do %>
<input type="hidden" name="_method" value="delete">
<%= submit_tag t('doorkeeper.authorized_applications.buttons.revoke'), onclick: "return confirm('#{ t('doorkeeper.authorized_applications.confirmations.revoke') }')", class: submit_btn_css %>
<% end %>

View File

@ -0,0 +1,25 @@
<header class="page-header">
<h1><%= t('doorkeeper.authorized_applications.index.title') %></h1>
</header>
<main role="main">
<table class="table table-striped">
<thead>
<tr>
<th><%= t('doorkeeper.authorized_applications.index.application') %></th>
<th><%= t('doorkeeper.authorized_applications.index.created_at') %></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @applications.each do |application| %>
<tr>
<td><%= application.name %></td>
<td><%= application.created_at.strftime(t('doorkeeper.authorized_applications.index.date_format')) %></td>
<td><%= render 'delete_form', application: application %></td>
</tr>
<% end %>
</tbody>
</table>
</main>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Doorkeeper</title>
<%= stylesheet_link_tag "doorkeeper/admin/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<%= link_to t('doorkeeper.layouts.admin.nav.oauth2_provider'), oauth_applications_path, class: 'navbar-brand' %>
</div>
<ul class="nav navbar-nav">
<%= content_tag :li, class: "#{'active' if request.path == oauth_applications_path}" do %>
<%= link_to t('doorkeeper.layouts.admin.nav.applications'), oauth_applications_path %>
<% end %>
<%= content_tag :li do %>
<%= link_to 'Home', root_path %>
<% end %>
</ul>
</div>
</div>
<div class="container">
<%- if flash[:notice].present? %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end -%>
<%= yield %>
</div>
</body>
</html>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title><%= t('doorkeeper.layouts.application.title') %></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= stylesheet_link_tag "doorkeeper/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="container">
<%- if flash[:notice].present? %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end -%>
<%= yield %>
</div>
</body>
</html>