diff --git a/Gemfile.lock b/Gemfile.lock index f97d5f9128b3660afd5c71726d93f55fab402077..173c4cd951d54bccc257cfe0eb887dc348f045c8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,7 +44,7 @@ GEM erubis (~> 2.7.0) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - active_model_serializers (0.10.5) + active_model_serializers (0.10.6) actionpack (>= 4.1, < 6) activemodel (>= 4.1, < 6) case_transform (>= 0.2) @@ -58,14 +58,14 @@ GEM activemodel (= 5.0.0.1) activesupport (= 5.0.0.1) arel (~> 7.0) - activerecord-import (0.17.2) + activerecord-import (0.18.2) activerecord (>= 3.2) activesupport (5.0.0.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - acts_as_list (0.9.4) + acts_as_list (0.9.5) activerecord (>= 3.0) addressable (2.5.1) public_suffix (~> 2.0, >= 2.0.2) @@ -124,8 +124,8 @@ GEM dm-validations (~> 1.2.0) data_objects (0.10.17) addressable (~> 2.1) - database_cleaner (1.5.3) - dawnscanner (1.6.7) + database_cleaner (1.6.1) + dawnscanner (1.6.8) cvss data_mapper dm-sqlite-adapter @@ -137,7 +137,7 @@ GEM sqlite3 sys-uname terminal-table - debug_inspector (0.0.2) + debug_inspector (0.0.3) derailed_benchmarks (1.3.2) benchmark-ips (~> 2) get_process_mem (~> 0) @@ -194,12 +194,12 @@ GEM dm-core (~> 1.2.0) do_sqlite3 (0.10.17) data_objects (= 0.10.17) - elasticsearch (5.0.3) - elasticsearch-api (= 5.0.3) - elasticsearch-transport (= 5.0.3) - elasticsearch-api (5.0.3) + elasticsearch (5.0.4) + elasticsearch-api (= 5.0.4) + elasticsearch-transport (= 5.0.4) + elasticsearch-api (5.0.4) multi_json - elasticsearch-transport (5.0.3) + elasticsearch-transport (5.0.4) faraday multi_json equalizer (0.0.11) @@ -218,7 +218,7 @@ GEM feature (1.4.0) ffi (1.9.18) flamegraph (0.9.5) - flay (2.8.1) + flay (2.9.0) erubis (~> 2.7.0) path_expander (~> 1.0) ruby_parser (~> 3.0) @@ -228,17 +228,17 @@ GEM ruby_parser (~> 3.1, > 3.1.0) sexp_processor (~> 4.8) get_process_mem (0.2.1) - gitlab (3.7.0) - httparty (~> 0.13.0) - terminal-table - globalid (0.3.7) - activesupport (>= 4.1.0) - haml (4.0.7) + gitlab (4.0.0) + httparty + terminal-table (= 1.7.1) + globalid (0.4.0) + activesupport (>= 4.2.0) + haml (5.0.1) + temple (>= 0.8.0) tilt hashie (3.5.5) heapy (0.1.2) - httparty (0.13.7) - json (~> 1.8) + httparty (0.14.0) multi_xml (>= 0.5.2) i18n (0.8.1) ice_nine (0.11.2) @@ -255,7 +255,7 @@ GEM logger-colors (1.0.0) loofah (2.0.3) nokogiri (>= 1.5.9) - mail (2.6.4) + mail (2.6.5) mime-types (>= 1.16, < 4) memory_profiler (0.9.8) method_source (0.8.2) @@ -267,7 +267,7 @@ GEM open4 (~> 1.3.4) rake mini_portile2 (2.1.0) - minitest (5.10.1) + minitest (5.10.2) minitest-reporters (1.1.14) ansi builder @@ -277,9 +277,10 @@ GEM multi_xml (0.6.0) multipart-post (2.0.0) mustache (1.0.5) + mustermann (1.0.0) net-http-persistent (2.9.4) nio4r (1.2.1) - nokogiri (1.7.1) + nokogiri (1.7.2) mini_portile2 (~> 2.1.0) oauth (0.5.1) oauth2 (1.3.1) @@ -309,7 +310,7 @@ GEM rack open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (6.0.2) + paper_trail (7.0.2) activerecord (>= 4.0, < 5.2) request_store (~> 1.1) paperclip (5.1.0) @@ -320,7 +321,7 @@ GEM mimemagic (~> 0.3.0) parser (2.4.0.0) ast (~> 2.2) - path_expander (1.0.1) + path_expander (1.0.2) pg (0.20.0) phantomjs (2.1.1.0) powerpack (0.1.1) @@ -334,13 +335,13 @@ GEM puma (3.8.2) pundit (1.1.0) activesupport (>= 3.0.0) - rack (2.0.1) + rack (2.0.2) rack-attack (5.0.1) rack rack-cors (0.4.1) rack-mini-profiler (0.10.2) rack (>= 1.2.0) - rack-protection (1.5.3) + rack-protection (2.0.0) rack rack-test (0.6.3) rack (>= 1.0) @@ -372,46 +373,48 @@ GEM method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.2.1) + rainbow (2.2.2) + rake rake (11.3.0) rdoc (4.3.0) redis (3.3.3) - reek (4.5.6) + reek (4.6.2) codeclimate-engine-rb (~> 0.4.0) - parser (>= 2.3.1.2, < 2.5) + parser (>= 2.4.0.0, < 2.5) rainbow (~> 2.0) request_store (1.3.2) resource_kit (0.1.6) addressable (>= 2.3.6, < 3.0.0) - responders (2.3.0) - railties (>= 4.2.0, < 5.1) + responders (2.4.0) + actionpack (>= 4.2.0, < 5.3) + railties (>= 4.2.0, < 5.3) rmagick (2.16.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-rails (3.5.2) + rspec-support (~> 3.6.0) + rspec-rails (3.6.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-support (~> 3.5.0) - rspec-support (3.5.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) rspec_api_documentation (4.9.0) activesupport (>= 3.0.0) mustache (~> 1.0, >= 0.99.4) rspec (~> 3.0) - rubocop (0.48.0) + rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) @@ -419,7 +422,7 @@ GEM unicode-display_width (~> 1.0, >= 1.0.1) ruby-graphviz (1.2.3) ruby-progressbar (1.8.1) - ruby_parser (3.8.4) + ruby_parser (3.9.0) sexp_processor (~> 4.1) rubycritic (3.2.0) flay (~> 2.8) @@ -436,26 +439,29 @@ GEM sdoc (0.4.2) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - searchkick (1.3.6) - activemodel + searchkick (2.3.0) + activemodel (>= 4.1) elasticsearch (>= 1) hashie - sexp_processor (4.8.0) + sexp_processor (4.9.0) shoulda (3.5.0) shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (>= 1.4.1, < 3.0) shoulda-context (1.2.2) shoulda-matchers (2.8.0) activesupport (>= 3.0.0) - sidekiq (4.2.10) + sidekiq (5.0.0) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) - redis (~> 3.2, >= 3.2.1) - sinatra (1.0) - rack (>= 1.0) - slim (3.0.7) - temple (~> 0.7.6) + redis (~> 3.3, >= 3.3.3) + sinatra (2.0.0) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.0) + tilt (~> 2.0) + slim (3.0.8) + temple (>= 0.7.6, < 0.9) tilt (>= 1.3.3, < 2.1) spring (2.0.1) activesupport (>= 4.2) @@ -472,8 +478,8 @@ GEM stringex (1.5.1) sys-uname (1.0.3) ffi (>= 1.0.0) - temple (0.7.7) - terminal-table (1.7.3) + temple (0.8.0) + terminal-table (1.7.1) unicode-display_width (~> 1.1.1) thor (0.19.4) thread_safe (0.3.6) @@ -559,7 +565,7 @@ DEPENDENCIES rubyzip screencap sdoc (~> 0.4.0) - searchkick (~> 1.3.6) + searchkick shoulda sidekiq sinatra diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb index 7f407e86f9eaee3d0e123786c00f192471442ca2..c986f3c70c1685e470c08ae7103c34870aa12634 100644 --- a/app/builders/learning_object_builder.rb +++ b/app/builders/learning_object_builder.rb @@ -7,6 +7,7 @@ class LearningObjectBuilder metadata: dspace_metadata_to_hash(item.metadata) ) + lo.curator = lo.get_metadata_value_of('dc.curator') institution = lo.get_metadata_value_of('dc.creator') institution = 'Desconhecido' if institution.blank? lo.publisher = Institution.where(name: institution).first_or_create diff --git a/app/controllers/concerns/followable_controller.rb b/app/controllers/concerns/followable_controller.rb index d703c163162c3a8bca651319c9d23ace9ac06303..40cd9139c58200a605c9275eebad11669c096657 100644 --- a/app/controllers/concerns/followable_controller.rb +++ b/app/controllers/concerns/followable_controller.rb @@ -4,7 +4,7 @@ module FollowableController extend ActiveSupport::Concern included do - before_action :authenticate_user!, only: [:follow, :unfollow] + before_action :authenticate_user!, only: [:follow, :unfollow, :follow_toggle] end # POST /v1/users/1/follow @@ -28,4 +28,18 @@ module FollowableController render status: :forbidden end end + + # PUT /v1/users/1/follow + # PUT /v1/users/1/follow.json + def follow_toggle + if !current_user.following?(followable) + current_user.follow(followable) + render status: :created + elsif current_user.following?(followable) + current_user.unfollow(followable) + render status: :ok + else + render status: :forbidden + end + end end diff --git a/app/controllers/v1/collections_controller.rb b/app/controllers/v1/collections_controller.rb index 2c8bf8df05159cf2ca8ac9b82cd2228df33c62af..de2f898e974414262eba88d13e6842292f5a851a 100644 --- a/app/controllers/v1/collections_controller.rb +++ b/app/controllers/v1/collections_controller.rb @@ -9,10 +9,10 @@ class V1::CollectionsController < ApplicationController include ::SubjectableController include ::StageableController - before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging] - before_action :set_collection, only: [:show, :update, :destroy, :add_object, :delete_object, :subjecting, :unsubjecting, :add_stages, :remove_stages] + before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging, :follow, :unfollow, :follow_toggle] + before_action :set_collection, only: [:show, :update, :destroy, :add_object, :delete_object, :subjecting, :unsubjecting, :add_stages, :remove_stages, :follow, :unfollow, :follow_toggle] before_action :set_new_collection, only: :index - before_action :authorize!, except: [:create, :tagging, :untagging, :follow, :unfollow, :download] + before_action :authorize!, except: [:create, :tagging, :untagging, :download] # GET /v1/collections # GET /v1/collections.json @@ -56,6 +56,10 @@ class V1::CollectionsController < ApplicationController # DELETE /v1/collections/1 # DELETE /v1/collections/1.json def destroy + items = @collection.collection_items.select(:id) + if !items.blank? + @collection.delete_items(items) + end @collection.destroy render status: :ok end @@ -99,7 +103,7 @@ class V1::CollectionsController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def collection_params - params.require(:collection).permit(:name, :description, :owner_id, :owner_type, :privacy, tags: []) + params.require(:collection).permit(:name, :curator, :description, :owner_id, :owner_type, :privacy, tags: []) end def extra_params diff --git a/app/controllers/v1/feed_controller.rb b/app/controllers/v1/feed_controller.rb index cd1aeb110f26b4f7787d676647ac57d7cacb8f28..fa14de1c21071ea92ecfae088c9e36b28ace5aaf 100644 --- a/app/controllers/v1/feed_controller.rb +++ b/app/controllers/v1/feed_controller.rb @@ -1,5 +1,6 @@ class V1::FeedController < ApplicationController include ::Paginator + include ActivitiesFilterService before_action :authenticate_user! # GET v1/feed @@ -13,11 +14,25 @@ class V1::FeedController < ApplicationController private def activities_followed - activities = [] + query = "" + values = [""] + + # builds a query string to find all relevant activities current_user.watching.each do |watching| - activities.push(*watching.activities_filtered.to_a) + if !watching.respond_to?(:state) || watching.state == "published" + # Activities that are made by, owned by, or change the object you follow should be found + query += " (trackable_type = ? and trackable_id = ?) or (owner_type = ? and owner_id = ?) or (recipient_type = ? and recipient_id = ?) or" + values << watching.class.to_s + values << watching.id + values << watching.class.to_s + values << watching.id + values << watching.class.to_s + values << watching.id + end end - activities + + values[0] = query[0..-3] # remove trailing "or" on the query + return PublicActivity::Activity.where(key: activities_filter).where(values).order(created_at: :desc) end end diff --git a/app/controllers/v1/institutions_controller.rb b/app/controllers/v1/institutions_controller.rb index aa549a8809893c27775b5c0b4bfc8120386d30e7..3d8627f77c0d83c6f476073bce040687b61707b2 100644 --- a/app/controllers/v1/institutions_controller.rb +++ b/app/controllers/v1/institutions_controller.rb @@ -5,6 +5,7 @@ class V1::InstitutionsController < ApplicationController before_action :set_institution, only: [:show, :update, :destroy, :users] before_action :authenticate_user!, only: [:create, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET v1/institutions # GET v1/institutions.json @@ -23,6 +24,7 @@ class V1::InstitutionsController < ApplicationController # POST v1/institutions.json def create institution = Institution.new(institution_params) + authorize institution if institution.save render json: institution, status: :created @@ -67,4 +69,8 @@ class V1::InstitutionsController < ApplicationController params.require(:institution).permit(:name, :description, :address, :city, :country) end + def authorize! + authorize @institution + end + end diff --git a/app/controllers/v1/learning_objects_controller.rb b/app/controllers/v1/learning_objects_controller.rb index ad9935aa1361acecc8e1f0e33ee04d6cd9d4ed49..2b274844ece406954e64eaf05ddf56eb59d880ad 100644 --- a/app/controllers/v1/learning_objects_controller.rb +++ b/app/controllers/v1/learning_objects_controller.rb @@ -13,7 +13,7 @@ class V1::LearningObjectsController < ApplicationController before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging] before_action :set_learning_object, only: [:show, :update, :destroy, :subjecting, :unsubjecting, :add_stages, :remove_stages] before_action :set_new_learning_object, only: :index - before_action :authorize!, except: [:create, :tagging, :untagging, :download] + before_action :authorize!, except: [:create, :tagging, :untagging, :download, :magnetlink] before_action :set_paper_trail_whodunnit, except: [:index, :show] def index @@ -39,7 +39,7 @@ class V1::LearningObjectsController < ApplicationController publisher = LearningObjectPublisher.new(DspaceService.create_client) if publisher.create_draft(learning_object, current_user) - learning_object_associations(learning_object) + learning_object_associations(learning_object, false) render json: learning_object, status: :created else render json: learning_object.errors, status: :unprocessable_entity @@ -49,8 +49,11 @@ class V1::LearningObjectsController < ApplicationController # PATCH/PUT /learning_objects/1 # PATCH/PUT /learning_objects/1.json def update + if !learning_object_params[:object_type_id].blank? && learning_object_params[:object_type_id] != @learning_object.object_type_id && learning_object_params[:link].blank? + change_object_type_id = true + end if @learning_object.update(learning_object_params) - learning_object_associations(@learning_object) + learning_object_associations(@learning_object, change_object_type_id) publisher = LearningObjectPublisher.new(DspaceService.create_client) publisher.update_dspace(@learning_object) @@ -63,10 +66,16 @@ class V1::LearningObjectsController < ApplicationController # DELETE /learning_objects/1 # DELETE /learning_objects/1.json def destroy - LearningObject.destroy(@learning_object) + @learning_object.destroy render status: :ok end + # GET /v1/learning_objects/magnetlink/:magnetlink + def magnetlink + render json: LearningObject.where(magnetlink: params[:magnetlink]) + end + + private def deleted_resource; LearningObject; end @@ -94,7 +103,7 @@ class V1::LearningObjectsController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def learning_object_params return nil if params[:learning_object].nil? - params[:learning_object].permit(:author, :name, :object_type_id, :description, :license_id, :thumbnail, :software, :language_id, :link) + params[:learning_object].permit(:author, :name, :curator, :object_type_id, :description, :license_id, :thumbnail, :software, :language_id, :link, :magnetlink) end def extra_params @@ -102,7 +111,7 @@ class V1::LearningObjectsController < ApplicationController params[:learning_object].permit(subjects: [], educational_stages: [], tags: [:name]) end - def learning_object_associations(learning_object) + def learning_object_associations(learning_object, change_object_type_id) if extra_params[:tags] == [] current_user.untag(learning_object, with: @learning_object.tags.map { |t| t['name'] }) elsif !extra_params[:tags].nil? @@ -110,6 +119,9 @@ class V1::LearningObjectsController < ApplicationController end learning_object.add_subjects(ids: extra_params[:subjects]) unless extra_params[:subjects].nil? learning_object.add_educational_stages(ids: extra_params[:educational_stages]) unless extra_params[:educational_stages].nil? + if change_object_type_id + learning_object.link = nil + end end def authorize! diff --git a/app/controllers/v1/licenses_controller.rb b/app/controllers/v1/licenses_controller.rb index a9bd87aa97cea7b4f0ae950fab257b702f35db7c..a97356de64b62ab28ffe3fd97d3d575500af7905 100644 --- a/app/controllers/v1/licenses_controller.rb +++ b/app/controllers/v1/licenses_controller.rb @@ -1,6 +1,7 @@ class V1::LicensesController < ApplicationController before_action :authenticate_user!, only: [:create, :update, :destroy] before_action :set_license, only: [:show, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET /licenses # GET /licenses.json @@ -18,6 +19,7 @@ class V1::LicensesController < ApplicationController # POST /licenses.json def create @license = License.new(license_params) + authorize @license if @license.save render json: @license, status: :created @@ -55,4 +57,8 @@ class V1::LicensesController < ApplicationController def license_params params.require(:license).permit(:name, :description, :url, :image_url) end + + def authorize! + authorize @license + end end diff --git a/app/controllers/v1/mime_types_controller.rb b/app/controllers/v1/mime_types_controller.rb index b7b65bd9ea1731b30a0088b5d8355b38a881bb31..e51e6f8783a22f0bf5b6676d40c19b8d6a3ae59c 100644 --- a/app/controllers/v1/mime_types_controller.rb +++ b/app/controllers/v1/mime_types_controller.rb @@ -3,6 +3,7 @@ class V1::MimeTypesController < ApplicationController before_action :authenticate_user!, except: [:index, :show] before_action :set_mime_type, only: [:show, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET /mime_types # GET /mime_types.json @@ -21,6 +22,7 @@ class V1::MimeTypesController < ApplicationController # POST /mime_types.json def create @mime_type = MimeType.new(mime_type_params) + authorize @mime_type if @mime_type.save render json: @mime_type, status: :created @@ -57,4 +59,8 @@ class V1::MimeTypesController < ApplicationController def mime_type_params params.require(:mime_type).permit(:extension, :mime_type) end + + def authorize! + authorize @mime_type + end end diff --git a/app/controllers/v1/object_types_controller.rb b/app/controllers/v1/object_types_controller.rb index cec8dbc49fb8674d73afdd581875fbb674be0e0f..c09775a85912a94520632acc37863dabd353b6d8 100644 --- a/app/controllers/v1/object_types_controller.rb +++ b/app/controllers/v1/object_types_controller.rb @@ -3,6 +3,7 @@ class V1::ObjectTypesController < ApplicationController before_action :authenticate_user!, except: [:index, :show] before_action :set_object_type, only: [:show, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET /object_types @@ -22,6 +23,7 @@ class V1::ObjectTypesController < ApplicationController # POST /object_types.json def create @object_type = ObjectType.new(sanitazed_params) + authorize @object_type if @object_type.save render json: @object_type, status: :created @@ -70,4 +72,8 @@ class V1::ObjectTypesController < ApplicationController end mime_params end + + def authorize! + authorize @object_type + end end diff --git a/app/controllers/v1/ratings_controller.rb b/app/controllers/v1/ratings_controller.rb index 90262e2c89dbab5e81285385da52fe675747a26d..d32fdea57779f5e0087d78954fdea7ec4ed1834e 100644 --- a/app/controllers/v1/ratings_controller.rb +++ b/app/controllers/v1/ratings_controller.rb @@ -3,6 +3,7 @@ class V1::RatingsController < ApplicationController before_action :set_rating, only: [:show, :update, :destroy] before_action :authenticate_user!, only: [:create, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET v1/ratings # GET v1/ratings.json @@ -20,6 +21,7 @@ class V1::RatingsController < ApplicationController # POST v1/ratings.json def create rating = Rating.new(rating_params) + authorize rating if rating.save render json: rating, status: :created @@ -59,4 +61,7 @@ class V1::RatingsController < ApplicationController params.require(:rating).permit(:name, :description) end + def authorize! + authorize @rating + end end diff --git a/app/controllers/v1/roles_controller.rb b/app/controllers/v1/roles_controller.rb index d8ecdc508f5700b395ff9a6b0833f89a3f8c4ffb..e846d8be87646057a08d0f272fedbefbdcc6d0f8 100644 --- a/app/controllers/v1/roles_controller.rb +++ b/app/controllers/v1/roles_controller.rb @@ -3,6 +3,7 @@ class V1::RolesController < ApplicationController before_action :authenticate_user!, except: [:index, :show] before_action :set_role, only: [:show, :update, :destroy] + before_action :authorize!, only: [:update, :destroy] # GET /roles # GET /roles.json @@ -21,6 +22,7 @@ class V1::RolesController < ApplicationController # POST /roles.json def create @role = Role.new(role_params) + authorize @role if @role.save render json: @role, status: :created @@ -57,4 +59,8 @@ class V1::RolesController < ApplicationController def role_params params.require(:role).permit(:name, :description) end + + def authorize! + authorize @role + end end diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index f6ffbdccc5e4bd00346cdfe927c1ec138a361d77..6405a2a8f37c861d02efd0cd4e8e5b74f46257f4 100644 --- a/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -7,7 +7,7 @@ class V1::UsersController < ApplicationController before_action :set_user, only: [:show, :update, :destroy, :following, :own_reviews, :received_reviews, :followers] before_action :authenticate_user!, only: [:create, :update, :destroy, :following, :own_reviews, :received_reviews, :followers] - before_action :authorize_user, only: [:own_reviews, :received_reviews] + before_action :authorize_user, only: [:own_reviews, :received_reviews, :update, :destroy] # GET /v1/users # GET /v1/users.json @@ -26,6 +26,7 @@ class V1::UsersController < ApplicationController # POST /v1/users.json def create user = User.new(user_params) + authorize user if user.save render json: user, status: :created @@ -53,12 +54,8 @@ class V1::UsersController < ApplicationController # DELETE /v1/users/1 # DELETE /v1/users/1.json def destroy - if current_user.is_admin? - @user.destroy - render status: :ok - else - render status: :forbidden - end + @user.destroy + render status: :ok end def following diff --git a/app/models/collection.rb b/app/models/collection.rb index 632f2179105d5b251b5c79986c978475df9afd0c..cecb90f16d4d75fd3d81ab94a9ad6a647a919c06 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -36,6 +36,8 @@ class Collection < ApplicationRecord include Highlights include Complainable + acts_as_paranoid + has_many :collection_items, -> { order("position ASC") }, as: :collectionable, dependent: :destroy has_many :collections, through: :collection_items, source: :collectionable, source_type: 'Collection' has_many :learning_objects, through: :collection_items, source: :collectionable, source_type: 'LearningObject' @@ -50,7 +52,6 @@ class Collection < ApplicationRecord searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author], callbacks: :async - acts_as_paranoid has_paper_trail def search_data diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb index 4fc48636bdb07fefc3468a79dc6dce01bafcb704..101e61d5b41f8ed4479647b771bfeccd66ac31aa 100644 --- a/app/models/collection_item.rb +++ b/app/models/collection_item.rb @@ -21,10 +21,20 @@ class CollectionItem < ApplicationRecord validates :collection, :collectionable, presence: true acts_as_list scope: :collection + acts_as_paranoid + def recipient collection end + def public? + collectionable.privacy == 'public' + end + + def owner?(candidate) + collectionable.owner == candidate + end + def thumbnail collectionable_type == 'LearningObject' ? LearningObject.find(collectionable_id).default_thumbnail : Collection.find(collectionable_id).thumbnail end diff --git a/app/models/concerns/trackable.rb b/app/models/concerns/trackable.rb index f51750fa4569e81a7c66864dcc6c5c8a112aafce..44ba3eee9b7fbe44177674f4fce4f426781b2aef 100644 --- a/app/models/concerns/trackable.rb +++ b/app/models/concerns/trackable.rb @@ -23,15 +23,17 @@ module Trackable end def new_destroy_activity - new_activity(:destroy) + params = { name: self.try(:name)} + new_activity(:destroy,params) end - def new_activity(action) + def new_activity(action,params=nil) create_activity( action, owner: activity_owner, recipient: activity_recipient, - privacy: activity_privacy + privacy: activity_privacy, + parameters: params ) end diff --git a/app/models/institution.rb b/app/models/institution.rb index 45a283350e02c5ba95fc64a7719a99d999954026..cd6d6909f302ebe89246ded0b07ee93e04c7922b 100644 --- a/app/models/institution.rb +++ b/app/models/institution.rb @@ -21,6 +21,9 @@ class Institution < ApplicationRecord #has_many :learning_objects, as: :publisher #has_many :collections, as: :owner + has_attached_file :avatar, styles: { medium: '300x300>', thumb: '60x60>' }, default_url: '' + validates_attachment_content_type :avatar, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'] + validates_presence_of :name acts_as_paranoid diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb index dee6c17462c6d9b7a1ff8bfbe3529ccf0b69ac49..1b43fe4703e90081be526923e0438ae85112e551 100644 --- a/app/models/learning_object.rb +++ b/app/models/learning_object.rb @@ -152,4 +152,8 @@ class LearningObject < ApplicationRecord def user_category publisher.try('user_category') end + + def ignore_changes + super + %w(score views_count downloads_count likes_count shares_count attachment_id) + end end diff --git a/app/models/role.rb b/app/models/role.rb index 9a9797ceaa545174bf97ded84a843df1854a9f80..cfca39dabe6eeebef6f979abc706df1a85db1220 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -29,4 +29,8 @@ class Role < ApplicationRecord def self.curator find_by(name: 'curator') || create!(name: 'curator') end + + def self.moderator + find_by(name: 'moderator') || create!(name: 'moderator') + end end diff --git a/app/models/search.rb b/app/models/search.rb index b74f038095c60c29b08fdcf1fa3dc36107ee4675..cb88cb4b1aa8a59bb0c8c7e3a680c3cfb2eeadaf 100644 --- a/app/models/search.rb +++ b/app/models/search.rb @@ -28,7 +28,7 @@ class Search { query: '*', order: 'score', - page: 1, + page: 0, results_per_page: 10 }.select { |key, _value| !params.key?(key) } end diff --git a/app/models/user.rb b/app/models/user.rb index a68598c89afae37d02363749e9d3cf099514464c..1399f3b6c95e4b49413c25b5634e0eed3bc39b92 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -42,7 +42,6 @@ class User < ApplicationRecord include Complainable include Publisher include Trackable - include ActivitiesFilterService # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable @@ -100,6 +99,17 @@ class User < ApplicationRecord false end + def is_moderator? + roles.each do |role| + return true if role.name == 'moderator' + end + false + end + + def can_moderate? + self.is_admin? || self.is_moderator? + end + def associated_collections c = collections.blank? ? [] : collections.to_a institutions.each { |i| c.push(*i.collections.to_a) } diff --git a/app/policies/activity_policy.rb b/app/policies/activity_policy.rb index dcd8537d416fd5173da8c7dfb855a02307419c83..bdb94fe88f7f4dfd1425050ad26c15881995b46e 100644 --- a/app/policies/activity_policy.rb +++ b/app/policies/activity_policy.rb @@ -9,7 +9,7 @@ class ActivityPolicy < ApplicationPolicy end def resolve - if user.is_admin? + if user_can_moderate? scope.includes(:owner,:recipient).order('created_at DESC').all else scope.includes(:owner,:recipient).where("privacy = 'public'").where(key: activities_filter).order('created_at DESC').all diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index dd6cb01af37e15c8298d8f66b68a69c6459b00dd..8445518d31b69544549342d4e8d3713371ef7266 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -40,7 +40,7 @@ class ApplicationPolicy def owns? return false if user.nil? - return true if user.is_admin? + return true if user_can_moderate? return owner.users.include?(user) if owner.is_a?(Institution) @@ -55,7 +55,11 @@ class ApplicationPolicy raise 'You must implement this method!' end - class Scope + def user_can_moderate? + user.is_admin? || user.is_moderator? + end + + class Scope < ApplicationPolicy attr_reader :user, :scope def initialize(user, scope) diff --git a/app/policies/bookmark_policy.rb b/app/policies/bookmark_policy.rb index dc25263844f2545838f6bb8ff582a4bc1929c87f..9e88edd4e4faf8c85857c5e1251cdbdd53a3fda8 100644 --- a/app/policies/bookmark_policy.rb +++ b/app/policies/bookmark_policy.rb @@ -17,7 +17,7 @@ class BookmarkPolicy < ApplicationPolicy end def user_own? - record.user == user || user.is_admin? + record.user == user || user_can_moderate? end end diff --git a/app/policies/collection_policy.rb b/app/policies/collection_policy.rb index 7ca595c7cd867bdbaf48d7f9c858c140a0fe1a21..9721408518245252b7fb8482729dd1a5005be1c3 100644 --- a/app/policies/collection_policy.rb +++ b/app/policies/collection_policy.rb @@ -7,8 +7,12 @@ class CollectionPolicy < ApplicationPolicy class Scope < Scope def resolve - if !user.nil? && user.is_admin? - scope.all + if user_exists? + if user_can_moderate? + scope.all + else + scope.includes(:collection_items).where.not(:collection_items => {:collection_id => nil}).where("privacy = ? OR owner_id = ?", 'public', user.id) + end else scope.includes(:collection_items).where.not(:collection_items => {:collection_id => nil}).where(privacy: 'public') end diff --git a/app/policies/followable_policy.rb b/app/policies/followable_policy.rb index 17aba92708f7ba0ea0ddd702d95a22cb1fc1c3e6..c3b5870e6dc8d28f74f98112e4263f2bf8f59b9e 100644 --- a/app/policies/followable_policy.rb +++ b/app/policies/followable_policy.rb @@ -7,4 +7,8 @@ module FollowablePolicy def unfollow? record if user_exists? end + + def follow_toggle? + record if user_exists? + end end diff --git a/app/policies/institution_policy.rb b/app/policies/institution_policy.rb index 0a9fd33439e5ae30939be78b647c24ed1589bc9a..185b3eff64311035233e7e87ac34d5a5118f7726 100644 --- a/app/policies/institution_policy.rb +++ b/app/policies/institution_policy.rb @@ -1,21 +1,21 @@ class InstitutionPolicy < ApplicationPolicy def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def index? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end def users? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/language_policy.rb b/app/policies/language_policy.rb index 71b94f7e72f4cc50a8e0ffe6b803f12a6b8d3a44..cae7a10e077c056d7bdc33099c8563f7c665ae38 100644 --- a/app/policies/language_policy.rb +++ b/app/policies/language_policy.rb @@ -8,14 +8,14 @@ class LanguagePolicy < ApplicationPolicy end def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/learning_object_policy.rb b/app/policies/learning_object_policy.rb index b35e77b0de8910086dc3d272455a2648d59ab8e9..b223bcaaf43220d5a70e59d189c4a3ef2084b60e 100644 --- a/app/policies/learning_object_policy.rb +++ b/app/policies/learning_object_policy.rb @@ -9,7 +9,7 @@ class LearningObjectPolicy < ApplicationPolicy def resolve if user.nil? scope.where(state: 'published') - elsif user.is_admin? + elsif user_can_moderate? scope.all else scope.where(state: 'published') @@ -38,9 +38,10 @@ class LearningObjectPolicy < ApplicationPolicy end def show? - return record if record.published? || user.try(:is_admin?) + return record if record.published? || ( !user.nil? && user_can_moderate? ) return record if user == record.publisher ## TODO: falta verificar se o +record.publisher+ é uma instituição e +user+ faz parte + # => return owner.users.include?(user) if owner.is_a?(Institution) (???) end def index? diff --git a/app/policies/license_policy.rb b/app/policies/license_policy.rb index adb7750ca3bdd3402ead90e2f67e32907d7b7e76..de80c911f15fa5ef6c9bac992de8c6ce64dfb9a1 100644 --- a/app/policies/license_policy.rb +++ b/app/policies/license_policy.rb @@ -8,14 +8,14 @@ class LicensePolicy < ApplicationPolicy end def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/mime_type_policy.rb b/app/policies/mime_type_policy.rb index 346a574db3fb9111fabc7b26aea277a91edbf5af..1ae25251480b629b8f32ab74fde50b6fa3487fd8 100644 --- a/app/policies/mime_type_policy.rb +++ b/app/policies/mime_type_policy.rb @@ -8,14 +8,14 @@ class MimeTypePolicy < ApplicationPolicy end def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/object_type_policy.rb b/app/policies/object_type_policy.rb index bdce7f229836f176915c27fc1f120e24753651b0..22633e5495565d96d8e5eecbe6ab746ca09e7c61 100644 --- a/app/policies/object_type_policy.rb +++ b/app/policies/object_type_policy.rb @@ -8,14 +8,14 @@ class ObjectTypePolicy < ApplicationPolicy end def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/publisher_policy.rb b/app/policies/publisher_policy.rb index 1da55efa6a5d9278f9825d2e174d261f25d5bef2..24158d58757c5c4930f38ebcb678faa1d0b18fb4 100644 --- a/app/policies/publisher_policy.rb +++ b/app/policies/publisher_policy.rb @@ -12,7 +12,7 @@ module PublisherPolicy def resolve if user.nil? scope.where(privacy: 'public') - elsif user.is_admin? || record == user + elsif user_can_moderate? || record == user scope.all else scope.where(privacy: 'public') @@ -21,15 +21,15 @@ module PublisherPolicy end def show_all_drafts? - record if same_user? || user.is_admin? + record if same_user? || user_can_moderate? end def show_liked_learning_objects? - record if same_user? || user.is_admin? + record if same_user? || user_can_moderate? end def show_liked_collections? - record if same_user? || user.is_admin? + record if same_user? || user_can_moderate? end def same_user? diff --git a/app/policies/rating_policy.rb b/app/policies/rating_policy.rb index e9155e1aa4809b51d730b6417031b3f76fcff3cb..bd3c49072adb60883c86d765be2e8926d5f7800e 100644 --- a/app/policies/rating_policy.rb +++ b/app/policies/rating_policy.rb @@ -9,14 +9,14 @@ class RatingPolicy < ApplicationPolicy end def create? - record if user.is_admin? + record if user_can_moderate? end def update? - record if user.is_admin? + record if user_can_moderate? end def destroy? - record if user.is_admin? + record if user_can_moderate? end end diff --git a/app/policies/search_policy.rb b/app/policies/search_policy.rb index 441469b63a9139414365770650ffca9a7c959fcf..7a3d5808659afaf64f687ceb144b8a5a52782225 100644 --- a/app/policies/search_policy.rb +++ b/app/policies/search_policy.rb @@ -3,7 +3,7 @@ class SearchPolicy < ApplicationPolicy def resolve if user.nil? scope.where(state: 'published') - elsif user.is_admin? + elsif user_can_moderate? scope.all else scope.where(state: 'published') diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index d8a1c1deb574c07bc01a6be654ff0223c99ca12f..1deecdaa6cceb05152e697ad2d39b25499c86dda 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -5,23 +5,37 @@ class UserPolicy < ApplicationPolicy class Scope < PublisherPolicy::Scope; end def update? - record if same_user? || user.is_admin? + record if same_user? || authorized_user? end def create? - user.is_admin? + authorized_user? end def show? record if user_exists? end - def own_reviews? + def destroy? record if same_user? || user.is_admin? end + def own_reviews? + record if same_user? || user_can_moderate? + end + def received_reviews? - record if same_user? || user.is_admin? + record if same_user? || user_can_moderate? + end + + def authorized_user? + return false if ( record.is_admin? && !user.is_admin? ) + if ( record.is_moderator? ) + if !( same_user? || user.is_admin? ) + return false + end + end + user_can_moderate? end def same_user? diff --git a/app/policies/welcome_policy.rb b/app/policies/welcome_policy.rb index 5d5ae66c95e757dbb5bf6b88f8dbd8c09710abbd..5062601c3ce3c61f9f2c9c409dd275d8965f7b95 100644 --- a/app/policies/welcome_policy.rb +++ b/app/policies/welcome_policy.rb @@ -1,7 +1,7 @@ class WelcomePolicy < ApplicationPolicy class Scope < Scope def resolve - if user.is_admin? + if user_can_moderate? scope.all else scope.where(state: 'published') diff --git a/app/serializers/collection_item_serializer.rb b/app/serializers/collection_item_serializer.rb index e085d36a8ac68a814ded456d5fa347827b08cabc..5bb19b6e93ff72cc1afd1059f2fa57c4f2197c3f 100644 --- a/app/serializers/collection_item_serializer.rb +++ b/app/serializers/collection_item_serializer.rb @@ -1,9 +1,18 @@ class CollectionItemSerializer < ActiveModel::Serializer cache key: 'collection_item', expires_in: 24.hours + def collectionable - serializer = object.collectionable_type == "LearningObject" ? ::LearningObjectSerializer : ::CollectionMinSerializer - serializer.new(object.collectionable, {scope: current_user, scope_name: :current_user}).serializable_hash + if ( object.collectionable_type == "LearningObject" ) + serializer = ::LearningObjectSerializer + elsif ( object.public? || (current_user && ( object.owner?(current_user) || current_user.can_moderate? )) ) + serializer = ::CollectionMinSerializer + end + + if ( !serializer.blank? ) + serializer.new(object.collectionable, {scope: current_user, scope_name: :current_user}).serializable_hash + end end + belongs_to :collectionable, polymorphic: true attributes :id, :position, :collectionable, :collectionable_type end diff --git a/app/serializers/collection_serializer.rb b/app/serializers/collection_serializer.rb index 94f6bf6ce48c750ca922f5861f90359671b4ff15..f945282c2a26db20e6134fd75757f399f56e6e52 100644 --- a/app/serializers/collection_serializer.rb +++ b/app/serializers/collection_serializer.rb @@ -14,7 +14,7 @@ class CollectionSerializer < ActiveModel::Serializer end def followed - object.followed? current_user + current_user.try(:following?, object) end def items_thumbnails @@ -28,7 +28,7 @@ class CollectionSerializer < ActiveModel::Serializer thumbs end - attributes :id, :name, :created_at, :updated_at, :description, :privacy, :score, :likes_count, :liked, :followed, :reviewed, :complained, :review_average, :thumbnail, :items_thumbnails + attributes :id, :name, :curator, :created_at, :updated_at, :description, :privacy, :score, :likes_count, :liked, :followed, :reviewed, :complained, :review_average, :thumbnail, :items_thumbnails belongs_to :owner has_many :tags diff --git a/app/serializers/follow_serializer.rb b/app/serializers/follow_serializer.rb index 5cf3d5147a7441062d416159021903f862ff01f8..ba5ee0682b26cf970310a272a257b52a2298c444 100644 --- a/app/serializers/follow_serializer.rb +++ b/app/serializers/follow_serializer.rb @@ -1,9 +1,12 @@ class FollowSerializer < ActiveModel::Serializer cache key: 'follow', expires_in: 24.hours + attributes :id + def follower object.user end - attributes :id, :follower, :followable + belongs_to :followable + belongs_to :follower end diff --git a/app/serializers/institution_serializer.rb b/app/serializers/institution_serializer.rb index 5de724635d138036ba37c13f2768f38b30266734..8b7d169d6c25a531061e9531bd4461e3f0634097 100644 --- a/app/serializers/institution_serializer.rb +++ b/app/serializers/institution_serializer.rb @@ -1,4 +1,4 @@ class InstitutionSerializer < ActiveModel::Serializer cache key: 'institution', expires_in: 4.hours - attributes :id, :name, :description, :address, :city, :country, :created_at, :updated_at + attributes :id, :name, :description, :address, :city, :country, :avatar, :created_at, :updated_at end diff --git a/app/serializers/learning_object_serializer.rb b/app/serializers/learning_object_serializer.rb index c1d51518ec5aee29bee9284c3c9b1f6da3271571..dbf2316da5ffef31800398cd2389208f4475a2bb 100644 --- a/app/serializers/learning_object_serializer.rb +++ b/app/serializers/learning_object_serializer.rb @@ -34,6 +34,7 @@ class LearningObjectSerializer < ActiveModel::Serializer :name, :description, :author, + :curator, :thumbnail, :object_type, :language, @@ -52,7 +53,8 @@ class LearningObjectSerializer < ActiveModel::Serializer :complained, :shares_count, :created_at, - :updated_at + :updated_at, + :magnetlink belongs_to :publisher has_many :tags diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index e8d1f3e82dff625186ab5e63fd3c95cfd39edcec..8a840883fb6e311d21280abf4e0a81735a26cd22 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -6,13 +6,17 @@ class UserSerializer < ActiveModel::Serializer end def followed - object.followed? current_user + current_user.try( :following?, object) end def email object.email if (current_user != nil)&&(object.id == current_user.id || current_user.is_admin?) end + def learning_objects_count + object.learning_objects.where('state = ?', LearningObject.states[:published]).count + end + attributes :id, :email, :provider, :name, :description, :education, :score, :cover, :role_ids, :institution_ids, :avatar, :likes_count, :followed, :complained, :follows_count, :learning_objects_count, :collections_count, :created_at, :updated_at has_many :subjects end diff --git a/app/services/learning_object_publisher.rb b/app/services/learning_object_publisher.rb index 096eff5bb2173550bddfab410e9d9b183b01eabf..c646d533d02bff320b1eafd62ef93c0be62a960f 100644 --- a/app/services/learning_object_publisher.rb +++ b/app/services/learning_object_publisher.rb @@ -68,7 +68,8 @@ class LearningObjectPublisher 'dc.type' => object.object_type.try(:name), 'dc.rights.license' => object.license.try(:name), # 'dc.subject.category' => object.subjects, - 'dc.date.submitted' => object.created_at.to_s + 'dc.date.submitted' => object.created_at.to_s, + 'dc.curator' => object.curator } end end diff --git a/app/services/search_service/collection.rb b/app/services/search_service/collection.rb index 5bd29469709d51634c3d8489b27f653afed1edd1..a66407af69bdd841364fda3bacc41a781dce315b 100644 --- a/app/services/search_service/collection.rb +++ b/app/services/search_service/collection.rb @@ -1,7 +1,7 @@ module SearchService class Collection < Model def search - ::Collection.search(query: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::Collection.search(body: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -39,6 +39,7 @@ module SearchService when 'likes' then { likes: { order: :desc } } when 'downloads' then { downloads: { order: :desc } } when 'review_average' then { review_average: { order: :desc } } + else "_score" end end diff --git a/app/services/search_service/learning_object.rb b/app/services/search_service/learning_object.rb index bff63f89f5d272e4c242eab493cea34bac8e619f..6ae89d3edc218c5ca370797e83f8b418e93a1df7 100644 --- a/app/services/search_service/learning_object.rb +++ b/app/services/search_service/learning_object.rb @@ -2,7 +2,7 @@ module SearchService class LearningObject < Model def search fields = [:license, :tags, :subjects, :educational_stages, :taggings, :publisher, :language, :attachments, :reviews] - ::LearningObject.search(query: mount_query, includes: fields, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::LearningObject.search(body: mount_query, includes: fields, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -40,6 +40,7 @@ module SearchService when 'likes' then { likes: { order: :desc } } when 'downloads' then { downloads: { order: :desc } } when 'review_average' then { review_average: { order: :desc } } + else "_score" end end diff --git a/app/services/search_service/model.rb b/app/services/search_service/model.rb index d37c3fc8909628ef068b3ff8f1ecf7bb3f54f1c7..20ca0ad586e5db35ee5a5cd70104b7818403076c 100644 --- a/app/services/search_service/model.rb +++ b/app/services/search_service/model.rb @@ -38,24 +38,36 @@ module SearchService def mount_query match_all_query = { - bool: { - must: { - match_all: {} - }, - filter: mount_filter - } + query: { + bool: { + must: { + match_all: {} + }, + filter: mount_filter + } + }, + size: @search.results_per_page, + from: ((@search.page.to_i) * (@search.results_per_page.to_i)).to_s, + sort: order_hash } return match_all_query if @search.query == '*' - { - function_score: { - query: { bool: { - must: { dis_max: { queries: mount_queries } }, - filter: mount_filter - } }, - functions: [{ script_score: { script: { lang: 'groovy', file: 'calculate_score' } } }] - } - } + { + query:{ + function_score: { + query: { bool: { + must: { dis_max: { queries: mount_queries } }, + filter: mount_filter + } }, + functions: [{ script_score: { script: { lang: 'groovy', file: 'calculate_score' } } }] + } + }, + # https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html + # Comeca pagina 0 + size: @search.results_per_page, + from: ((@search.page.to_i) * (@search.results_per_page.to_i)).to_s, + sort: order_hash + } end def mount_queries diff --git a/app/services/search_service/user.rb b/app/services/search_service/user.rb index c9afd7790f52d404f93c74aa426155a4d24bcc0a..03898bdc3ac84c6c30bbc046843abb86b34deb45 100644 --- a/app/services/search_service/user.rb +++ b/app/services/search_service/user.rb @@ -1,7 +1,7 @@ module SearchService class User < Model def search - ::User.search(query: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::User.search(body: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -20,7 +20,7 @@ module SearchService def order_hash return { name: { order: :asc, unmapped_type: :string } } if @search.order == 'title' - nil + "_score" end end end diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb new file mode 100644 index 0000000000000000000000000000000000000000..e591a06b27196300668419e7f35019e6aef8f257 --- /dev/null +++ b/config/initializers/elasticsearch.rb @@ -0,0 +1,6 @@ +Searchkick.client = + Elasticsearch::Client.new( + url: 'localhost:9200', + transport_options: {request: {timeout: 550}} + ) + diff --git a/config/routes.rb b/config/routes.rb index c314a4533c81a8bfed191612d32c3f98c73169e8..2ef9a747bce42a72c79b623e5ba1d374077703ee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,7 @@ Rails.application.routes.draw do member do post 'follow', as: :follow, action: :follow delete 'follow', as: :unfollow, action: :unfollow + put 'follow', as: :follow_toggle, action: :follow_toggle end end @@ -154,5 +155,6 @@ Rails.application.routes.draw do get '/subjects', to: 'subjects#index' get '/educational_stages', to: 'educational_stages#index' get '/activities/me', to: 'activities#me' + get 'learning_objects/magnetlink/:magnetlink', to: 'learning_objects#magnetlink', as: 'magnetlink_learning_objects' end end diff --git a/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb b/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb new file mode 100644 index 0000000000000000000000000000000000000000..fee56386d833200d0c3faa7ff8a379d817bdbca7 --- /dev/null +++ b/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb @@ -0,0 +1,11 @@ +class AddAttachmentAvatarToInstitutions < ActiveRecord::Migration + def self.up + change_table :institutions do |t| + t.attachment :avatar + end + end + + def self.down + remove_attachment :institutions, :avatar + end +end diff --git a/db/migrate/20170511161146_add_curator_to_learning_object.rb b/db/migrate/20170511161146_add_curator_to_learning_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..d722347d41c2a6de5bcc448e21740fe0e7d31b8e --- /dev/null +++ b/db/migrate/20170511161146_add_curator_to_learning_object.rb @@ -0,0 +1,5 @@ +class AddCuratorToLearningObject < ActiveRecord::Migration[5.0] + def change + add_column :learning_objects, :curator, :string + end +end diff --git a/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb b/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..6ee102f5debee49368eaa5e8f2f9e0094393be85 --- /dev/null +++ b/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb @@ -0,0 +1,5 @@ +class AddMagnetlinkToLearningObject < ActiveRecord::Migration[5.0] + def change + add_column :learning_objects, :magnetlink, :string + end +end \ No newline at end of file diff --git a/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb b/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb new file mode 100644 index 0000000000000000000000000000000000000000..abbe878fe27d87f74b19feeed88a854d25c1b020 --- /dev/null +++ b/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb @@ -0,0 +1,6 @@ +class AddDeletedAtToCollectionItems < ActiveRecord::Migration[5.0] + def change + add_column :collection_items, :deleted_at, :datetime + add_index :collection_items, :deleted_at + end +end \ No newline at end of file diff --git a/db/migrate/20170518120936_add_curator_to_collection.rb b/db/migrate/20170518120936_add_curator_to_collection.rb new file mode 100644 index 0000000000000000000000000000000000000000..29f69c17c5c0c588d4eb3cf98152b367cb921a34 --- /dev/null +++ b/db/migrate/20170518120936_add_curator_to_collection.rb @@ -0,0 +1,5 @@ +class AddCuratorToCollection < ActiveRecord::Migration[5.0] + def change + add_column :collections, :curator, :string + end +end diff --git a/db/migrate/20170525120237_add_learning_objects_count_to_institutions.rb b/db/migrate/20170525120237_add_learning_objects_count_to_institutions.rb new file mode 100644 index 0000000000000000000000000000000000000000..e8f42351b6122341a8a1a3d00fd0860f8405bbc4 --- /dev/null +++ b/db/migrate/20170525120237_add_learning_objects_count_to_institutions.rb @@ -0,0 +1,5 @@ +class AddLearningObjectsCountToInstitutions < ActiveRecord::Migration[5.0] + def change + add_column :institutions, :learning_objects_count, :integer, default: 0 + end +end \ No newline at end of file diff --git a/db/seeds.rb b/db/seeds.rb index 785a3bb76dff904dad91bd36d3402903fc6dc368..0a4ba3ef41205d37cb528b959212f029f5151c89 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -9,6 +9,7 @@ Role.create(name: 'teacher', description: 'This role represents a Teacher in Por Role.create(name: 'student', description: 'This role represents a Student in Portal MEC.') Role.create(name: 'admin', description: 'This role represents an MEC Admin, that can perform any action.') Role.create(name: 'curator', description: 'This role represents a content Curator in Portal MEC.') +Role.create(name: 'moderator', description: 'This role represents a content Moderator in Portal MEC, with less privileges than admin.') # create the default admin User.create( diff --git a/lib/portalmec/sociable_tests.rb b/lib/portalmec/sociable_tests.rb index b7dbc33010ee5f050b29f0f485512594efc0c913..822eff0d8b9c7a83d9ecb43f5e579b2f01cbd1e2 100644 --- a/lib/portalmec/sociable_tests.rb +++ b/lib/portalmec/sociable_tests.rb @@ -1,3 +1,5 @@ +require 'active_support' + module Portalmec::SociableTests extend ActiveSupport::Testing::Declarative diff --git a/spec/acceptance/activities_spec.rb b/spec/acceptance/activities_spec.rb index cb9193f80a09a2118c2620718ff2ed5795c8585b..d20694caab25dde3fd8206e6b51f7dc58214b9bc 100644 --- a/spec/acceptance/activities_spec.rb +++ b/spec/acceptance/activities_spec.rb @@ -40,9 +40,10 @@ resource 'Activities' do include_context "authenticate_user" let(:id) { users.first.id } - + before do create(:follow, followable: users.first, user: @user) + create(:like, user: users.first) end example 'Showing activities from a specific user' do @@ -56,7 +57,8 @@ resource 'Activities' do include_context "authenticate_user" before do - create(:like, user: @user) + create(:follow, followable: users.first, user: @user) + create(:like, user: users.first) end example 'Showing all activities that logged user can see' do diff --git a/spec/acceptance/downloads_spec.rb b/spec/acceptance/downloads_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..63526173338a8362af4875c793b3b78982287b9e --- /dev/null +++ b/spec/acceptance/downloads_spec.rb @@ -0,0 +1,28 @@ +require 'acceptance_helpers' +require 'shared/contexts' + +resource 'Downloads' do + + explanation "An user can download the content of a learning object or collection." + + get '/v1/:type/:id/download' do + include_context "authenticate_user" + + parameter :type, "Represents the type of object [‘learning_objects’,'collections']", scope: :download + parameter :id, "The id of object", scope: :download + + let(:type) { 'learning_objects' } + let(:id) { @learning_object.id } + + + before do + @learning_object = create(:learning_object, publisher: @user) + create(:attachment, learning_object: @learning_object) + end + + example_request 'Download an object' do + expect(status).to eq(302) + end + end + +end diff --git a/spec/acceptance/educational_stages_spec.rb b/spec/acceptance/educational_stages_spec.rb index b7d7f85d952ffecc4cb5530d310fe1ea51483003..31358de607b296f643cd855bfbe5e696b0394f9c 100644 --- a/spec/acceptance/educational_stages_spec.rb +++ b/spec/acceptance/educational_stages_spec.rb @@ -42,7 +42,7 @@ resource 'Educational Stages' do end delete '/v1/:type/:id/educational_stages' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, 'The id of object' parameter :type, 'Represents the type of object, [learning_objects, collection]' diff --git a/spec/acceptance/institutions_spec.rb b/spec/acceptance/institutions_spec.rb index 986f63691fc725f4cef0669b35d40f50a95bbf6c..dd64f06306edbb3f09a7620c7f9f8e83fc567db5 100644 --- a/spec/acceptance/institutions_spec.rb +++ b/spec/acceptance/institutions_spec.rb @@ -36,7 +36,7 @@ resource 'Institutions' do end post '/v1/institutions' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :name, 'The name of the institution' parameter :description, 'The description of the institution' @@ -58,7 +58,7 @@ resource 'Institutions' do end put '/v1/institutions/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, 'The id of the institution' parameter :name, 'The name of the institution' @@ -82,7 +82,7 @@ resource 'Institutions' do end delete '/v1/institutions/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, 'The id of the institution' diff --git a/spec/acceptance/learning_objects_spec.rb b/spec/acceptance/learning_objects_spec.rb index 02bbc1c7182425cb2a8d3e53b4fc7bfdc6edd573..13a8a4f2019d4e938d9b0ef9621b6bd70185530c 100644 --- a/spec/acceptance/learning_objects_spec.rb +++ b/spec/acceptance/learning_objects_spec.rb @@ -54,9 +54,13 @@ resource 'Learning Objects' do parameter :object_type_id, 'The id of object type', scope: :learning_object parameter :language_id, 'The id of a language', scope: :learning_object parameter :license_id, 'The id of a license', scope: :learning_object + parameter :curator, 'The name of curator', scope: :learning_object + parameter :thumbnail, 'The learning_object thumbnail', scope: :learning_object let(:author) { Faker::Name.name } let(:name) { Faker::Name.name } + let(:curator) { Faker::Name.name } + let(:thumbnail) { Faker::Avatar.image } let(:description) { Faker::Lorem.paragraph } let(:object_type_id) { object_types.first.id } let(:language_id) { languages.first.id } diff --git a/spec/acceptance/mime_types_spec.rb b/spec/acceptance/mime_types_spec.rb index 8be6e3c42d543a96c303ee314e7ece0b9f08fa61..5ba38318a7b294633c06b7f4eb8fea5ae8c43b28 100644 --- a/spec/acceptance/mime_types_spec.rb +++ b/spec/acceptance/mime_types_spec.rb @@ -26,7 +26,7 @@ resource 'Mime Types' do post '/v1/mime_types' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :extension, 'The name of the mime_type', scope: :mime_type parameter :mime_type, 'The mime_type', scope: :mime_type @@ -42,7 +42,7 @@ resource 'Mime Types' do end put '/v1/mime_types/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :extension, 'The name of the mime_type', scope: :mime_type parameter :mime_type, 'The mime_type', scope: :mime_type @@ -58,7 +58,7 @@ resource 'Mime Types' do end delete '/v1/mime_types/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" let(:id) { mime_types.first.id } diff --git a/spec/acceptance/object_types_spec.rb b/spec/acceptance/object_types_spec.rb index 862bc56352f79998caf2e95e7ed53993ebdf2058..35bb936faca04eed4ff51e4aac75a5fe16f87430 100644 --- a/spec/acceptance/object_types_spec.rb +++ b/spec/acceptance/object_types_spec.rb @@ -31,7 +31,7 @@ resource 'Object Type' do end post '/v1/object_types' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :name, 'The name of the object type', scope: :object_type parameter :mime_types, 'Array of mime_types', scope: :object_type @@ -48,7 +48,7 @@ resource 'Object Type' do delete 'v1/object_types/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, "The id of the object_type" @@ -61,7 +61,7 @@ resource 'Object Type' do end put '/v1/object_types/:id' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, "The id of the object_type" parameter :name, 'The name of the object type', scope: :object_type diff --git a/spec/acceptance/searches_spec.rb b/spec/acceptance/searches_spec.rb index 08d7a25020fc14693643e86571608449b1554928..967a2cab98dd32f5630475d6f4430422e09e4f1a 100644 --- a/spec/acceptance/searches_spec.rb +++ b/spec/acceptance/searches_spec.rb @@ -5,7 +5,7 @@ resource 'Searches' do explanation "Search is a query for Learning Objects, Collections or Users." before { 12.times { create(:learning_object); LearningObject.reindex } } - + get '/v1/search' do parameter :page, 'Results page number' @@ -19,9 +19,9 @@ resource 'Searches' do parameter :types, 'Filter the search by Learning Object object types, array of ids. Example: object_types[]=1&object_types[]=2' - let(:page) { 1 } + let(:page) { 0 } let(:results_per_page) { 12 } - let(:order) { "score" } + let(:order) { "_score" } let(:query) { "*" } let(:search_class) { "LearningObject" } @@ -49,10 +49,6 @@ resource 'Searches' do do_request expect(status).to eq(200) end - - - - end diff --git a/spec/acceptance/subjects_spec.rb b/spec/acceptance/subjects_spec.rb index 4c118babd3f1496ebf408c65edabeb8d6cad7384..0919110bbe7ce0f63acd6b0876ccd31142437b74 100644 --- a/spec/acceptance/subjects_spec.rb +++ b/spec/acceptance/subjects_spec.rb @@ -42,7 +42,7 @@ resource 'Subjects' do end delete 'v1/:type/:id/subjects' do - include_context "authenticate_user" + include_context "authenticate_user_admin" parameter :id, "The id of the object" parameter :type, "Represents the type of the object [LearningObject, Collection]" diff --git a/spec/acceptance/users_spec.rb b/spec/acceptance/users_spec.rb index ae60ec1687ac55b1ec9971f808d45bdea4d94dbe..47879acd8d98bd0bf842b864b2727fdf25c0743f 100644 --- a/spec/acceptance/users_spec.rb +++ b/spec/acceptance/users_spec.rb @@ -1,4 +1,5 @@ require 'acceptance_helpers' +require 'shared/contexts' resource 'Users' do header 'Accept', 'application/json' @@ -104,16 +105,12 @@ resource 'Users' do let(:password_confirmation) { '12345678' } let(:terms_of_service) { true } let(:avatar) {""} - # TODO role ids con't be changed if user isn't admin, send [] - # when it's a admin send [role.first.id] + # TODO role ids con't be changed if user isn't admin, send [] + # when it's a admin send [role.first.id] let(:roles_ids) { [] } let(:subjects) { [subject.first.id] } let(:raw_post) {params.to_json} - before do - @user = create(:user) - end - example 'Updating an user' do do_request expect(status).to eq(200) diff --git a/spec/factories/attachments.rb b/spec/factories/attachments.rb new file mode 100644 index 0000000000000000000000000000000000000000..4141d1e6493599412a40b9555cfbcdad6bef0d49 --- /dev/null +++ b/spec/factories/attachments.rb @@ -0,0 +1,10 @@ +FactoryGirl.define do + + factory :attachment, class: LearningObject::Attachment do |f| + f.name { Faker::Name.name } + f.retrieve_link { Faker::File.file_name } + f.mime_type { Faker::File.mime_type } + end + +end + diff --git a/spec/factories/downloads.rb b/spec/factories/downloads.rb new file mode 100644 index 0000000000000000000000000000000000000000..c4019c9f923dc119ff57c9667098e76f6a094ac2 --- /dev/null +++ b/spec/factories/downloads.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + + factory :download do |f| + f.ip { Faker::Internet.ip_v4_address } + downloadable + user + end + +end \ No newline at end of file