Project

General

Profile

Feature #24808 » 0004-oauth-Redmine-style-UI-for-Doorkeeper-OAuth2-provide.patch

Jens Krämer, 2020-07-21 13:05

View differences:

app/views/doorkeeper/applications/_form.html.erb
1
<%= error_messages_for 'application' %>
2
<div class="box tabular">
3
  <p><%= f.text_field :name, :required => true %></p>
4

  
5
  <p>
6
    <%= f.text_area :redirect_uri, :required => true, :size => 60, :label => :'activerecord.attributes.doorkeeper/application.redirect_uri' %>
7
    <em class="info">
8
      <%= t('doorkeeper.applications.help.redirect_uri') %>
9
      <% if Doorkeeper.configuration.native_redirect_uri %>
10
        <br/><%= raw t('doorkeeper.applications.help.native_redirect_uri',
11
                native_redirect_uri: "<code>#{ Doorkeeper.configuration.native_redirect_uri }</code>") %>
12
      <% end %>
13
    </em>
14
  </p>
15

  
16
  <p>
17
    <%= f.text_field :scopes, :size => 60, :label => :'activerecord.attributes.doorkeeper/application.scopes'  %>
18
    <em class="info">
19
      <%= t('doorkeeper.applications.help.scopes') %>
20
    </em>
21
  </p>
22

  
23

  
24

  
25
</div>
app/views/doorkeeper/applications/edit.html.erb
1
<%= title [t('doorkeeper.applications.index.title'), oauth_applications_path], @application.name %>
2

  
3
<%= labelled_form_for @application, url: doorkeeper_submit_path(@application) do |f| %>
4
  <%= render :partial => 'form', :locals => {:f => f} %>
5
  <%= submit_tag l(:button_save) %>
6
<% end %>
app/views/doorkeeper/applications/index.html.erb
1
<div class="contextual">
2
<%= link_to t('.new'), new_oauth_application_path, :class => 'icon icon-add' %>
3
</div>
4

  
5
<%= title t('.title') %>
6

  
7
<% if @applications.any? %>
8
<div class="autoscroll">
9
<table class="list">
10
  <thead><tr>
11
    <th><%= t('.name') %></th>
12
    <th><%= t('.callback_url') %></th>
13
    <th><%= t('.scopes') %></th>
14
    <th></th>
15
  </tr></thead>
16
  <tbody>
17
  <% @applications.each do |application| %>
18
    <tr id="application_<%= application.id %>" class="<%= cycle("odd", "even") %>">
19
      <td class="name"><span><%= link_to application.name, oauth_application_path(application) %></span></td>
20
      <td class="description"><%= truncate application.redirect_uri.split.join(', '), length: 50 %></td>
21
      <td class="description"><%= h application.scopes %></td>
22
      <td class="buttons">
23
        <%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'icon icon-edit' %>
24
        <%= link_to t('doorkeeper.applications.buttons.destroy'), oauth_application_path(application), :data => {:confirm => t('doorkeeper.applications.confirmations.destroy')}, :method => :delete, :class => 'icon icon-del' %>
25
      </td>
26
    </tr>
27
  <% end %>
28
  </tbody>
29
</table>
30
</div>
31
<% else %>
32
  <p class="nodata"><%= l(:label_no_data) %></p>
33
<% end %>
app/views/doorkeeper/applications/new.html.erb
1
<%= title [t('doorkeeper.applications.index.title'), oauth_applications_path], t('.title') %>
2

  
3
<%= labelled_form_for @application, url: doorkeeper_submit_path(@application)  do |f| %>
4
<%= render :partial => 'form', :locals => { :f => f } %>
5
<%= submit_tag l(:button_create) %>
6
<% end %>
app/views/doorkeeper/applications/show.html.erb
1
<div class="contextual">
2
<%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(@application), :accesskey => accesskey(:edit), class: 'icon icon-edit' %>
3
<%= link_to t('doorkeeper.applications.buttons.destroy'), oauth_application_path(@application), :data => {:confirm => t('doorkeeper.applications.confirmations.destroy')}, :method => :delete, :class => 'icon icon-del' %>
4
</div>
5

  
6
<%= title [t('doorkeeper.applications.index.title'), oauth_applications_path], @application.name %>
7

  
8
<div class="box">
9
  <h3 class="icon icon-passwd"><%= l(:label_information_plural) %></h3>
10
  <p>
11
    <span class="label"><%= t('.application_id') %>:</span>
12
    <code><%= h @application.uid %></code>
13
  </p>
14
  <p>
15
    <span class="label"><%= t('.secret') %>:</span>
16
    <code><%= h @application.secret %></code>
17
  </p>
18
  <p>
19
    <span class="label"><%= t('.scopes') %>:</span>
20
    <code><%= h @application.scopes %></code>
21
  </p>
22
</div>
23

  
24
<h3><%= t('.callback_urls') %></h3>
25

  
26
<div class="autoscroll">
27
<table class="list">
28
  <thead><tr>
29
    <th><%= t('.callback_url') %></th>
30
    <th></th>
31
  </tr></thead>
32
  <tbody>
33
  <% @application.redirect_uri.split.each do |uri| %>
34
    <tr class="<%= cycle("odd", "even") %>">
35
      <td class="name"><span><%= uri %></span></td>
36
      <td class="buttons">
37
        <%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code', scope: @application.scopes), class: 'icon icon-authorize', target: '_blank' %>
38
      </td>
39
    </tr>
40
  <% end %>
41
  </tbody>
42
</table>
43
</div>
app/views/doorkeeper/authorizations/error.html.erb
1
<h2><%= t('doorkeeper.authorizations.error.title') %></h2>
2

  
3
<p id="errorExplanation"><%= @pre_auth.error_response.body[:error_description] %></p>
4
<p><a href="javascript:history.back()"><%= l(:button_back) %></a></p>
5

  
6
<% html_title t('doorkeeper.authorizations.error.title') %>
app/views/doorkeeper/authorizations/new.html.erb
1
<%= title t('.title') %>
2

  
3
<div class="warning">
4
<p><strong><%=h @pre_auth.client.name %></strong></p>
5

  
6
<p><%= raw t('.prompt', client_name: "<strong class=\"text-info\">#{ @pre_auth.client.name }</strong>") %></p>
7

  
8
<% if @pre_auth.scopes.count > 0 %>
9
  <div class="oauth-permissions">
10
    <p><%= t('.able_to') %>:
11
    <ul>
12
      <% @pre_auth.scopes.each do |scope| %>
13
        <li><%= t scope, scope: [:doorkeeper, :scopes] %></li>
14
      <% end %>
15
    </ul>
16
    </p>
17
  </div>
18
<% end %>
19
</div>
20

  
21
<p>
22
  <%= form_tag oauth_authorization_path, method: :post do %>
23
    <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
24
    <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
25
    <%= hidden_field_tag :state, @pre_auth.state %>
26
    <%= hidden_field_tag :response_type, @pre_auth.response_type %>
27
    <%= hidden_field_tag :scope, @pre_auth.scope %>
28
    <%= submit_tag t('doorkeeper.authorizations.buttons.authorize') %>
29
  <% end %>
30
  <%= form_tag oauth_authorization_path, method: :delete do %>
31
    <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
32
    <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
33
    <%= hidden_field_tag :state, @pre_auth.state %>
34
    <%= hidden_field_tag :response_type, @pre_auth.response_type %>
35
    <%= hidden_field_tag :scope, @pre_auth.scope %>
36
    <%= submit_tag t('doorkeeper.authorizations.buttons.deny') %>
37
  <% end %>
38
</p>
app/views/doorkeeper/authorizations/show.html.erb
1
<%= title [t('doorkeeper.authorized_applications.index.title'), oauth_authorized_applications_path]  %>
2

  
3
<fieldset class="tabular"><legend><%= l(:label_information_plural) %></legend>
4
  <p>
5
    <label><%= t('.title') %>:</label>
6
    <code><%= params[:code] %></code>
7
  </p>
8
</fieldset>
app/views/doorkeeper/authorized_applications/index.html.erb
1
<%= title [t(:label_my_account), my_account_path], t('doorkeeper.authorized_applications.index.title') %>
2

  
3
<% if @applications.any? %>
4
<div class="autoscroll">
5
<table class="list">
6
  <thead><tr>
7
    <th><%= t('doorkeeper.authorized_applications.index.application') %></th>
8
    <th><%= t('doorkeeper.authorized_applications.index.created_at') %></th>
9
    <th></th>
10
  </tr></thead>
11
  <tbody>
12
  <% @applications.each do |application| %>
13
    <tr id="application_<%= application.id %>" class="<%= cycle("odd", "even") %>">
14
      <td class="name"><span><%= application.name %></span></td>
15
      <td ><%= format_date application.created_at %></td>
16
      <td class="buttons">
17
        <%= link_to t('doorkeeper.authorized_applications.buttons.revoke'), oauth_authorized_application_path(application), :data => {:confirm => t('doorkeeper.authorized_applications.confirmations.revoke')}, :method => :delete, :class => 'icon icon-del' %>
18
      </td>
19
    </tr>
20
  <% end %>
21
  </tbody>
22
</table>
23
</div>
24
<% else %>
25
  <p class="nodata"><%= l(:label_no_data) %></p>
26
<% end %>
27

  
28
<% content_for :sidebar do %>
29
<% @user = User.current %>
30
<%= render :partial => 'my/sidebar' %>
31
<% end %>
config/application.rb
81 81
      :key => '_redmine_session',
82 82
      :path => config.relative_url_root || '/'
83 83

  
84
    # Use Redmine standard layouts and helpers for Doorkeeper OAuth2 screens
85
    config.to_prepare do
86
      Doorkeeper::ApplicationsController.layout "admin"
87
      Doorkeeper::ApplicationsController.main_menu = false
88
      Doorkeeper::AuthorizationsController.layout "base"
89
      Doorkeeper::AuthorizedApplicationsController.layout "base"
90
      Doorkeeper::AuthorizedApplicationsController.main_menu = false
91
    end
92

  
84 93
    if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
85 94
      instance_eval File.read(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
86 95
    end
config/initializers/doorkeeper.rb
2 2
  use_refresh_token
3 3
  reuse_access_token
4 4
  realm           Redmine::Info.app_name
5
  base_controller 'ApplicationController'
5 6
  default_scopes  :public
6 7

  
7 8
  resource_owner_authenticator do
8
    if Setting.rest_api_enabled?
9
      User.active.find_by_id(session[:user_id]) || redirect_to(signin_path(:back_url => request.original_url))
10
    else
11
      render(:text => 'Forbidden', :status => 403)
9
    if require_login
10
      if Setting.rest_api_enabled?
11
        User.current
12
      else
13
        deny_access
14
      end
12 15
    end
13 16
  end
14 17

  
15 18
  admin_authenticator do
16
    if !Setting.rest_api_enabled? || !User.active.where(admin: true).find_by_id(session[:user_id])
17
      render(:text => 'Forbidden', :status => 403)
19
    if !Setting.rest_api_enabled? || !User.current.admin?
20
      deny_access
18 21
    end
19 22
  end
20

  
21 23
end
public/stylesheets/application.css
1022 1022
  color: #A6750C;
1023 1023
}
1024 1024

  
1025
.warning .oauth-permissions { display:inline-block;text-align:left; }
1026
.warning .oauth-permissions p { margin-top:0;-webkit-margin-before:0;}
1027

  
1025 1028
#errorExplanation ul { font-size: 0.9em;}
1026 1029
#errorExplanation h2, #errorExplanation p { display: none; }
1027 1030

  
......
1545 1548
.icon-custom-fields { background-image: url(../images/textfield.png); }
1546 1549
.icon-plugins { background-image: url(../images/plugin.png); }
1547 1550
.icon-applications { background-image: url(../images/application_view_tile.png); }
1551
.icon-authorize { background-image: url(../images/application_key.png); }
1548 1552
.icon-news { background-image: url(../images/news.png); }
1549 1553
.icon-issue-closed { background-image: url(../images/ticket_checked.png); }
1550 1554
.icon-issue-note { background-image: url(../images/ticket_note.png); }
(15-15/24)