Commit 5e21a5703f89af5a0ad05c8c38fb3d96937c8858

Authored by Leandro Santos
2 parents 9719a2da a0194228
Exists in staging and in 1 other branch production

mege with master

Gemfile
... ... @@ -27,7 +27,7 @@ gem 'rest-client', '~> 1.6'
27 27 gem 'exception_notification', '~> 4.0.1'
28 28 gem 'gettext', '~> 3.1', :require => false
29 29 gem 'locale', '~> 2.1'
30   -gem 'whenever', :require => false
  30 +gem 'whenever', '~> 0.9.4', :require => false
31 31 gem 'eita-jrails', '~> 0.10.0', require: 'jrails'
32 32 gem 'diffy', '~> 3.0'
33 33 gem 'slim'
... ...
Gemfile.lock
... ... @@ -489,7 +489,7 @@ DEPENDENCIES
489 489 unicorn (~> 4.8)
490 490 validates_as_cnpj (= 0.0.0)!
491 491 validates_multiparameter_assignments (= 0.0.0)!
492   - whenever
  492 + whenever (~> 0.9.4)
493 493 will_paginate (~> 3.0.7)
494 494 xss_terminate (= 0.0.0)!
495 495  
... ...
app/api/entities.rb
... ... @@ -174,6 +174,10 @@ module Api
174 174 expose :created_at, :format_with => :timestamp
175 175 expose :author, :using => Profile
176 176 expose :reply_of, :using => CommentBase
  177 + expose :permissions do |comment, options|
  178 + Entities.permissions_for_entity(comment, options[:current_person],
  179 + :allow_destroy?)
  180 + end
177 181 end
178 182  
179 183 class Comment < CommentBase
... ...
app/api/v1/session.rb
... ... @@ -174,14 +174,13 @@ module Api
174 174 # Example Request:
175 175 # PATCH /new_password?code=xxxx&password=secret&password_confirmation=secret
176 176 patch "/new_password" do
177   - change_password = ChangePassword.find_by code: params[:code]
178   - not_found! if change_password.nil?
179   -
180   - if change_password.update_attributes(:password => params[:password], :password_confirmation => params[:password_confirmation])
  177 + begin
  178 + change_password = ChangePassword.find_by! code: params[:code]
  179 + change_password.update_attributes!(:password => params[:password], :password_confirmation => params[:password_confirmation])
181 180 change_password.finish
182 181 present change_password.requestor.user, :with => Entities::UserLogin, :current_person => current_person
183   - else
184   - something_wrong!
  182 + rescue Exception => ex
  183 + render_api_error!(ex.message, 400)
185 184 end
186 185 end
187 186  
... ...
app/models/comment.rb
... ... @@ -212,6 +212,9 @@ class Comment &lt; ApplicationRecord
212 212 user == author || user == profile || user.has_permission?(:moderate_comments, profile)
213 213 end
214 214  
  215 + # method used by the API
  216 + alias_method :allow_destroy?, :can_be_destroyed_by?
  217 +
215 218 def can_be_marked_as_spam_by?(user)
216 219 return if user.nil?
217 220 user == profile || user.has_permission?(:moderate_comments, profile)
... ...
app/views/cms/edit.html.erb
... ... @@ -34,7 +34,7 @@
34 34  
35 35 <br />
36 36  
37   - <%= f.text_field('tag_list', :size => 64) %>
  37 + <%= f.text_field 'tag_list', size: 64, value: @article.tag_list.join(',') %>
38 38 <%= content_tag( 'small', _('Separate tags with commas') ) %>
39 39  
40 40 <script>
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -86,9 +86,9 @@
86 86 <%=
87 87 str = (@plugins.dispatch(:body_ending).map do |content|
88 88 if content.respond_to?(:call) then
89   - instance_exec(&content)
  89 + instance_exec(&content).html_safe
90 90 else
91   - content
  91 + content.html_safe
92 92 end
93 93 end)
94 94 safe_join(str, "\n")
... ...
plugins/oauth_client/lib/oauth_client_plugin.rb
... ... @@ -72,6 +72,7 @@ class OauthClientPlugin &lt; Noosfero::Plugin
72 72 strategy.options.merge! consumer_key: provider.client_id, consumer_secret: provider.client_secret
73 73 strategy.options.merge! client_id: provider.client_id, client_secret: provider.client_secret
74 74 strategy.options.merge! options
  75 + strategy.options.merge! provider.options
75 76  
76 77 request.session[:provider_id] = provider_id
77 78 }
... ...
plugins/oauth_provider/Gemfile
1   -source 'https://rubygems.org'
2   -gem 'doorkeeper', '~> 1.4.0'
3   -gem 'responders', '~> 2.0'
4   -gem 'rack', '1.6.4'
  1 +gem 'doorkeeper', '~> 3.1.0'
... ...
plugins/oauth_provider/controllers/doorkeeper/application_controller.rb
... ... @@ -2,7 +2,6 @@ module Doorkeeper
2 2 class ApplicationController < ApplicationController
3 3  
4 4 include Helpers::Controller
5   - helper 'doorkeeper/form_errors'
6 5  
7 6 end
8 7 end
... ...
plugins/oauth_provider/controllers/public/oauth_provider_plugin_public_controller.rb
1 1 class OauthProviderPluginPublicController < PublicController
2 2  
3   - doorkeeper_for :me
  3 + before_action :doorkeeper_authorize!
4 4  
5 5 def me
6 6 user = environment.users.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
... ...
plugins/oauth_provider/db/migrate/20160727164530_add_scopes_to_oauth_applications.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddScopesToOauthApplications < ActiveRecord::Migration
  2 + def change
  3 + add_column :oauth_applications, :scopes, :string, null: false, default: ''
  4 + end
  5 +end
... ...
plugins/oauth_provider/views/doorkeeper/applications/_delete_form.html.erb
1 1 <%- submit_btn_css ||= 'btn btn-link' %>
2   -<%= form_tag [:oauth, application] do %>
  2 +<%= form_tag oauth_application_path(application) do %>
3 3 <input type="hidden" name="_method" value="delete">
4   - <%= submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css %>
  4 + <%= submit_tag _('Destroy'), onclick: "return confirm('#{ _('Are you sure?') }')", class: submit_btn_css %>
5 5 <% end %>
... ...
plugins/oauth_provider/views/doorkeeper/applications/_form.html.erb
1   -<%= form_for [:oauth, application], html: {class: 'form-horizontal', role: 'form'} do |f| %>
  1 +<% extend Doorkeeper::DashboardHelper %>
  2 +<%= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f| %>
2 3 <% if application.errors.any? %>
3   - <div class="alert alert-danger" data-alert>
4   - <p><%= _('Whoops! Check your form for possible errors') %></p>
5   - </div>
  4 + <div class="alert alert-danger" data-alert><p><%= _('Whoops! Check your form for possible errors') %></p></div>
6 5 <% end %>
7 6  
8 7 <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do %>
9   - <%= f.label :name, class: 'col-sm-2 control-label', for: 'application_name' %>
  8 + <%= f.label :name, class: 'col-sm-2 control-label' %>
10 9 <div class="col-sm-10">
11 10 <%= f.text_field :name, class: 'form-control' %>
12 11 <%= doorkeeper_errors_for application, :name %>
... ... @@ -14,26 +13,36 @@
14 13 <% end %>
15 14  
16 15 <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do %>
17   - <%= f.label :redirect_uri, class: 'col-sm-2 control-label', for: 'application_redirect_uri' %>
  16 + <%= f.label :redirect_uri, class: 'col-sm-2 control-label' %>
18 17 <div class="col-sm-10">
19 18 <%= f.text_area :redirect_uri, class: 'form-control' %>
20 19 <%= doorkeeper_errors_for application, :redirect_uri %>
21 20 <span class="help-block">
22 21 <%= _('Use one line per URI') %>
23   - </span>
  22 + </span>
24 23 <% if Doorkeeper.configuration.native_redirect_uri %>
25 24 <span class="help-block">
26   - Use <code><%= Doorkeeper.configuration.native_redirect_uri %></code> for local tests
  25 + <%= raw _('Use %s to local tests') % "<code>#{ Doorkeeper.configuration.native_redirect_uri }</code>" %>
27 26 </span>
28 27 <% end %>
29 28 </div>
30 29 <% end %>
31 30  
  31 + <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:scopes].present?}" do %>
  32 + <%= f.label :scopes, class: 'col-sm-2 control-label' %>
  33 + <div class="col-sm-10">
  34 + <%= f.text_field :scopes, class: 'form-control' %>
  35 + <%= doorkeeper_errors_for application, :scopes %>
  36 + <span class="help-block">
  37 + <%= _('Separate scopes with spaces. Leave blank to use the default scopes.') %>
  38 + </span>
  39 + </div>
  40 + <% end %>
  41 +
32 42 <div class="form-group">
33 43 <div class="col-sm-offset-2 col-sm-10">
34 44 <%= f.submit _('Submit'), class: "btn btn-primary" %>
35   - <%= link_to _("Cancel"), oauth_applications_path, :class => "btn btn-default" %>
  45 + <%= link_to _('Cancel'), oauth_applications_path, :class => "btn btn-default" %>
36 46 </div>
37 47 </div>
38 48 <% end %>
39   -
... ...
plugins/oauth_provider/views/doorkeeper/applications/index.html.erb
1 1 <div class="oauth-provider">
2 2 <div class="page-header">
3   - <h3><%= link_to _('Oauh Provider'), '/admin/plugin/oauth_provider' %></h3>
  3 + <h1><%= _('Oauh Provider') %></h1>
4 4 </div>
5 5  
6 6 <p><%= link_to _('New Application'), new_oauth_application_path, class: 'btn btn-success' %></p>
... ... @@ -17,7 +17,7 @@
17 17 <tbody>
18 18 <% @applications.each do |application| %>
19 19 <tr id="application_<%= application.id %>">
20   - <td><%= link_to application.name, [:oauth, application] %></td>
  20 + <td><%= link_to application.name, oauth_application_path(application) %></td>
21 21 <td><%= application.redirect_uri %></td>
22 22 <td><%= link_to _('Edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td>
23 23 <td><%= render 'delete_form', application: application %></td>
... ...
plugins/oauth_provider/views/doorkeeper/applications/new.html.erb
1 1 <div class="page-header">
2   - <h1>New application</h1>
  2 + <h1><%= _('New application') %></h1>
3 3 </div>
4 4  
5 5 <%= render 'form', application: @application %>
... ...
plugins/oauth_provider/views/doorkeeper/applications/show.html.erb
... ... @@ -5,13 +5,14 @@
5 5 <div class="row">
6 6 <div class="col-md-8">
7 7 <h4><%= _('Application Id:') %></h4>
8   -
9 8 <p><code id="application_id"><%= @application.uid %></code></p>
10 9  
11 10 <h4><%= _('Secret:') %></h4>
12   -
13 11 <p><code id="secret"><%= @application.secret %></code></p>
14 12  
  13 + <h4><%= _('Scopes') %>:</h4>
  14 + <p><code id="scopes"><%= @application.scopes %></code></p>
  15 +
15 16 <h4><%= _('Callback urls:') %></h4>
16 17  
17 18 <table>
... ... @@ -21,6 +22,7 @@
21 22 <code><%= uri %></code>
22 23 </td>
23 24 <td>
  25 + <%= link_to _('Authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code'), class: 'btn btn-success', target: '_blank' %>
24 26 </td>
25 27 </tr>
26 28 <% end %>
... ...
plugins/oauth_provider/views/doorkeeper/authorizations/error.html.erb
1 1 <div class="page-header">
2   - <h1>An error has occurred</h1>
  2 + <h1><%= _('An error has occurred') %></h1>
3 3 </div>
4 4  
5 5 <main role="main">
... ...
plugins/oauth_provider/views/doorkeeper/authorizations/new.html.erb
1 1 <div class="oauth-provider-authorize">
2   -
3 2 <header class="page-header" role="banner">
4 3 <h1><%= _('Authorize required') %></h1>
5 4 </header>
6 5  
7 6 <main role="main">
8 7 <p class="h4">
9   - <%= _('Authorize %s to use your account?') % "<strong class=\"text-info\">#{@pre_auth.client.name}</strong>" %>
  8 + <%= _('Authorize %s to use your account?') % "<strong class=\"text-info\">#{@pre_auth.client.name}</strong>" %>
10 9 </p>
11 10  
12   - <% if @pre_auth.scopes %>
  11 + <% if @pre_auth.scopes.count > 0 %>
13 12 <div id="oauth-permissions">
14 13 <p><%= _('This application will be able to:') %></p>
15 14  
16 15 <ul class="text-info">
17 16 <% @pre_auth.scopes.each do |scope| %>
18   - <li><%= OauthProviderPlugin::SCOPE_TRANSLATION[scope] %></li>
  17 + <li><%= t scope, scope: [:doorkeeper, :scopes] %></li>
19 18 <% end %>
20 19 </ul>
21 20 </div>
... ... @@ -28,7 +27,7 @@
28 27 <%= hidden_field_tag :state, @pre_auth.state %>
29 28 <%= hidden_field_tag :response_type, @pre_auth.response_type %>
30 29 <%= hidden_field_tag :scope, @pre_auth.scope %>
31   - <%= submit_button :ok, _("Authorize") %>
  30 + <%= submit_tag _('Authorize'), class: "btn btn-success btn-lg btn-block" %>
32 31 <% end %>
33 32 <%= form_tag oauth_authorization_path, method: :delete do %>
34 33 <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
... ... @@ -36,7 +35,7 @@
36 35 <%= hidden_field_tag :state, @pre_auth.state %>
37 36 <%= hidden_field_tag :response_type, @pre_auth.response_type %>
38 37 <%= hidden_field_tag :scope, @pre_auth.scope %>
39   - <%= submit_button :cancel, _("Deny") %>
  38 + <%= submit_tag _('Deny'), class: "btn btn-danger btn-lg btn-block" %>
40 39 <% end %>
41 40 </div>
42 41 </main>
... ...
plugins/oauth_provider/views/doorkeeper/authorizations/show.html.erb
1 1 <header class="page-header">
2   - <h1>Authorization code:</h1>
  2 + <h1><%= _('Authorization code:') %></h1>
3 3 </header>
4 4  
5 5 <main role="main">
... ...
plugins/oauth_provider/views/doorkeeper/authorized_applications/_delete_form.html.erb
1 1 <%- submit_btn_css ||= 'btn btn-link' %>
2 2 <%= form_tag oauth_authorized_application_path(application) do %>
3 3 <input type="hidden" name="_method" value="delete">
4   - <%= submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: submit_btn_css %>
  4 + <%= submit_tag _('Revoke'), onclick: "return confirm('#{ _('Are you sure?') }')", class: submit_btn_css %>
5 5 <% end %>
... ...
plugins/oauth_provider/views/doorkeeper/authorized_applications/index.html.erb
1 1 <div class="oauth-provider">
2 2 <header class="page-header">
3   - <h1>Your authorized applications</h1>
  3 + <h1><%= _('Your authorized applications') %></h1>
4 4 </header>
5 5  
6 6 <main role="main">
7 7 <table class="table table-striped">
8 8 <thead>
9 9 <tr>
10   - <th>Application</th>
11   - <th>Created At</th>
  10 + <th><%= _('Application') %></th>
  11 + <th><%= _('Created at') %></th>
12 12 <th></th>
13 13 <th></th>
14 14 </tr>
... ... @@ -24,7 +24,6 @@
24 24 </tbody>
25 25 </table>
26 26 </main>
27   -
28 27 <div class="actions">
29 28 <%= button(:back, _('Go back'), :back) %>
30 29 </div>
... ...
test/api/comments_test.rb
... ... @@ -245,4 +245,34 @@ class CommentsTest &lt; ActiveSupport::TestCase
245 245 assert_equal 500, last_response.status
246 246 assert_includes article.comments, comment
247 247 end
  248 +
  249 + should 'list allow_destroy permission when get your own comment' do
  250 + login_api
  251 + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing")
  252 + article.comments.create!(:body => "some comment", :author => @person)
  253 + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  254 + json = JSON.parse(last_response.body)
  255 + assert_equal 200, last_response.status
  256 + assert_includes json["comments"][0]["permissions"], 'allow_destroy'
  257 + end
  258 +
  259 + should 'anonymous not allowed to destroy comments' do
  260 + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing")
  261 + article.comments.create!(:body => "some comment", :author => @person)
  262 + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  263 + json = JSON.parse(last_response.body)
  264 + assert_equal 200, last_response.status
  265 + assert_not_includes json["comments"][0]["permissions"], 'allow_destroy'
  266 + end
  267 +
  268 + should 'unprivileged user not be allowed to destroy other people comments' do
  269 + article = fast_create(Article, profile_id: @local_person.id, name: "Some thing")
  270 + comment = article.comments.create!(body: "some comment", author: @local_person)
  271 + login_api
  272 + get "/api/v1/articles/#{article.id}/comments?#{params.to_query}"
  273 + json = JSON.parse(last_response.body)
  274 + assert_equal 200, last_response.status
  275 + assert_not_includes json["comments"][0]["permissions"], 'allow_destroy'
  276 + end
  277 +
248 278 end
... ...
test/api/session_test.rb
... ... @@ -179,13 +179,19 @@ class SessionTest &lt; ActiveSupport::TestCase
179 179 patch "/api/v1/new_password?#{params.to_query}"
180 180 assert_equal Task::Status::ACTIVE, task.reload.status
181 181 assert !user.reload.authenticated?('secret')
  182 + json = JSON.parse(last_response.body)
  183 + assert_match /doesn't match/, json['message']
  184 +
182 185 assert_equal 400, last_response.status
183 186 end
184 187  
185 188 should 'render not found when provide a wrong code on password change' do
186 189 params = {:code => "wrongcode", :password => 'secret', :password_confirmation => 'secret'}
187 190 patch "/api/v1/new_password?#{params.to_query}"
188   - assert_equal 404, last_response.status
  191 + json = JSON.parse(last_response.body)
  192 + assert_match /Couldn't find/, json['message']
  193 +
  194 + assert_equal 400, last_response.status
189 195 end
190 196  
191 197 # FIXME this test fails i don't know if stil needed
... ...
test/unit/comment_test.rb
... ... @@ -597,6 +597,12 @@ class CommentTest &lt; ActiveSupport::TestCase
597 597 refute comment.can_be_destroyed_by?(nil)
598 598 end
599 599  
  600 + should 'anonymous has no allow_destroy? permission' do
  601 + comment = Comment.new
  602 +
  603 + refute comment.allow_destroy?(nil)
  604 + end
  605 +
600 606 should 'not be able to destroy comment' do
601 607 user = Person.new
602 608 profile = Profile.new
... ...