PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/app/controllers/usage_rights_controller.rb

https://gitlab.com/ykazemi/canvas-lms
Ruby | 178 lines | 48 code | 11 blank | 119 comment | 8 complexity | 43a75771a50fcedbe8b90c004e3b93cc MD5 | raw file
  1. #
  2. # Copyright (C) 2011 - 2014 Instructure, Inc.
  3. #
  4. # This file is part of Canvas.
  5. #
  6. # Canvas is free software: you can redistribute it and/or modify it under
  7. # the terms of the GNU Affero General Public License as published by the Free
  8. # Software Foundation, version 3 of the License.
  9. #
  10. # Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. # details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License along
  16. # with this program. If not, see <http://www.gnu.org/licenses/>.
  17. # @API Files
  18. # @subtopic Usage Rights
  19. #
  20. # @model UsageRights
  21. # {
  22. # "id": "UsageRights",
  23. # "description": "Describes the copyright and license information for a File",
  24. # "properties": {
  25. # "legal_copyright" : {
  26. # "type": "string",
  27. # "description": "Copyright line for the file",
  28. # "example": "(C) 2014 Incom Corporation Ltd"
  29. # },
  30. # "use_justification" : {
  31. # "type": "string",
  32. # "description": "Justification for using the file in a Canvas course. Valid values are 'own_copyright', 'public_domain', 'used_by_permission', 'fair_use', 'creative_commons'",
  33. # "example": "creative_commons"
  34. # },
  35. # "license" : {
  36. # "type": "string",
  37. # "description": "License identifier for the file.",
  38. # "example": "cc_by_sa"
  39. # },
  40. # "license_name": {
  41. # "type": "string",
  42. # "description": "Readable license name",
  43. # "example": "CC Attribution Share-Alike"
  44. # },
  45. # "message": {
  46. # "type": "string",
  47. # "description": "Explanation of the action performed",
  48. # "example": "4 files updated"
  49. # },
  50. # "file_ids": {
  51. # "description": "List of ids of files that were updated",
  52. # "type": "array",
  53. # "items": { "type": "integer" },
  54. # "example": [1, 2, 3]
  55. # }
  56. # }
  57. # }
  58. #
  59. # @model License
  60. # {
  61. # "id": "License",
  62. # "properties": {
  63. # "id": {
  64. # "type": "string",
  65. # "description": "a short string identifying the license",
  66. # "example": "cc_by_sa"
  67. # },
  68. # "name": {
  69. # "type": "string",
  70. # "description": "the name of the license",
  71. # "example": "CC Attribution ShareAlike"
  72. # },
  73. # "url": {
  74. # "type": "string",
  75. # "description": "a link to the license text",
  76. # "example": "http://creativecommons.org/licenses/by-sa/4.0"
  77. # }
  78. # }
  79. # }
  80. #
  81. class UsageRightsController < ApplicationController
  82. include Api::V1::UsageRights
  83. before_filter :require_context
  84. # @API Set usage rights
  85. # Sets copyright and license information for one or more files
  86. #
  87. # @argument file_ids[] [Required]
  88. # List of ids of files to set usage rights for.
  89. #
  90. # @argument folder_ids[] [Optional]
  91. # List of ids of folders to search for files to set usage rights for.
  92. # Note that new files uploaded to these folders do not automatically inherit these rights.
  93. #
  94. # @argument publish [Optional, Boolean]
  95. # Whether the file(s) or folder(s) should be published on save, provided that usage rights have been specified (set to `true` to publish on save).
  96. #
  97. # @argument usage_rights[use_justification] [Required, String, "own_copyright"|"used_by_permission"|"fair_use"|"public_domain"|"creative_commons"]
  98. # The intellectual property justification for using the files in Canvas
  99. #
  100. # @argument usage_rights[legal_copyright] [Optional, String]
  101. # The legal copyright line for the files
  102. #
  103. # @argument usage_rights[license] [Optional, String]
  104. # The license that applies to the files. See the {api:UsageRightsController#licenses List licenses endpoint} for the supported license types.
  105. #
  106. # @returns UsageRights
  107. def set_usage_rights
  108. if authorized_action(@context, @current_user, :manage_files)
  109. return render json: { message: I18n.t("Must supply 'file_ids' and/or 'folder_ids' parameter") }, status: :bad_request unless params[:file_ids].present? || params[:folder_ids].present?
  110. return render json: { message: I18n.t("No 'usage_rights' object supplied") }, status: :bad_request unless params[:usage_rights].is_a?(Hash)
  111. usage_rights_params = params[:usage_rights].slice(:use_justification, :legal_copyright, :license)
  112. usage_rights = @context.usage_rights.where(usage_rights_params).first
  113. usage_rights ||= @context.usage_rights.create(usage_rights_params)
  114. return render json: usage_rights.errors, status: :bad_request unless usage_rights && usage_rights.valid?
  115. assign_usage_rights(usage_rights)
  116. end
  117. end
  118. # @API Remove usage rights
  119. # Removes copyright and license information associated with one or more files
  120. #
  121. # @argument file_ids[] [Required]
  122. # List of ids of files to remove associated usage rights from.
  123. #
  124. # @argument folder_ids[] [Optional]
  125. # List of ids of folders. Usage rights will be removed from all files in these folders.
  126. #
  127. def remove_usage_rights
  128. if authorized_action(@context, @current_user, :manage_files)
  129. return render json: { message: I18n.t("Must supply 'file_ids' and/or 'folder_ids' parameter") }, status: :bad_request unless params[:file_ids].present? || params[:folder_ids].present?
  130. assign_usage_rights(nil)
  131. end
  132. end
  133. # @API List licenses
  134. # Lists licenses that can be applied
  135. #
  136. # @returns [License]
  137. def licenses
  138. # there are no per-context licenses yet, but let's pretend like there are, for future expandability
  139. if authorized_action(@context, @current_user, :read)
  140. render json: UsageRights.licenses.map { |license, data|
  141. { id: license, name: data[:readable_license], url: data[:license_url] }
  142. }
  143. end
  144. end
  145. private
  146. # recursively enumerate file ids under a folder
  147. def enumerate_contents(folder)
  148. ids = folder.active_sub_folders.inject([]) { |file_ids, folder| file_ids += enumerate_contents(folder) }
  149. ids += folder.active_file_attachments.pluck(:id)
  150. end
  151. # assign the given usage rights to params[:file_ids] / params[:folder_ids]
  152. def assign_usage_rights(usage_rights)
  153. folder_ids = Array(params[:folder_ids]).map(&:to_i)
  154. folders = @context.folders.active.where(id: folder_ids).to_a
  155. file_ids = folders.inject([]) { |file_ids, folder| file_ids += enumerate_contents(folder) }
  156. file_ids += @context.attachments.not_deleted.where(id: Array(params[:file_ids]).map(&:to_i)).pluck(:id)
  157. update_attrs = {usage_rights_id: usage_rights}
  158. update_attrs.merge!(locked: false) if usage_rights.present? && value_to_boolean(params[:publish])
  159. count = @context.attachments.not_deleted.where(id: file_ids).update_all(update_attrs)
  160. result = usage_rights ? usage_rights_json(usage_rights, @current_user) : {}
  161. result.merge!({
  162. message: I18n.t({one: "1 file updated", other: "%{count} files updated"}, count: count ),
  163. file_ids: file_ids
  164. })
  165. return render json: result
  166. end
  167. end