mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Warps logging implementations. Now on to error messages
This commit is contained in:
@@ -128,6 +128,7 @@ ignore_unused:
|
||||
- 'permission_*'
|
||||
- '{devise,kaminari,will_paginate}.*'
|
||||
- '*.permission_header_explanation'
|
||||
- 'services.*'
|
||||
|
||||
## Exclude these keys from the `i18n-tasks eq-base' report:
|
||||
# ignore_eq_base:
|
||||
|
||||
+42
-36
@@ -33,6 +33,8 @@ module Storages
|
||||
module StorageInteraction
|
||||
module Nextcloud
|
||||
class AddUserToGroupCommand
|
||||
include Snitch
|
||||
|
||||
def initialize(storage)
|
||||
@storage = storage
|
||||
@username = storage.username
|
||||
@@ -46,48 +48,52 @@ module Storages
|
||||
end
|
||||
|
||||
def call(user:, group: @group)
|
||||
response = OpenProject
|
||||
.httpx
|
||||
.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.post(
|
||||
UrlBuilder.url(@storage.uri, "ocs/v1.php/cloud/users", user, "groups"),
|
||||
form: { "groupid" => CGI.escapeURIComponent(group) }
|
||||
)
|
||||
with_tagged_logger do
|
||||
url = UrlBuilder.url(@storage.uri, "ocs/v1.php/cloud/users", user, "groups")
|
||||
info "Adding #{user} to #{group} through #{url}"
|
||||
|
||||
error_data = StorageErrorData.new(source: self.class, payload: response)
|
||||
response = OpenProject.httpx
|
||||
.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.post(
|
||||
UrlBuilder.url(@storage.uri, "ocs/v1.php/cloud/users", user, "groups"),
|
||||
form: { "groupid" => CGI.escapeURIComponent(group) }
|
||||
)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
statuscode = Nokogiri::XML(response.body.to_s).xpath("/ocs/meta/statuscode").text
|
||||
error_data = StorageErrorData.new(source: self.class, payload: response)
|
||||
|
||||
case statuscode
|
||||
when "100"
|
||||
ServiceResult.success(message: "User has been added successfully")
|
||||
when "101"
|
||||
Util.error(:error, "No group specified", error_data)
|
||||
when "102"
|
||||
Util.error(:error, "Group does not exist", error_data)
|
||||
when "103"
|
||||
Util.error(:error, "User does not exist", error_data)
|
||||
when "104"
|
||||
Util.error(:error, "Insufficient privileges", error_data)
|
||||
when "105"
|
||||
Util.error(:error, "Failed to add user to group", error_data)
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
statuscode = Nokogiri::XML(response.body.to_s).xpath("/ocs/meta/statuscode").text
|
||||
|
||||
case statuscode
|
||||
when "100"
|
||||
info "User has been added to the group"
|
||||
ServiceResult.success
|
||||
when "101"
|
||||
Util.error(:error, "No group specified", error_data)
|
||||
when "102"
|
||||
Util.error(:group_does_not_exist, "Group does not exist", error_data)
|
||||
when "103"
|
||||
Util.error(:user_does_not_exist, "User does not exist", error_data)
|
||||
when "104"
|
||||
Util.error(:insufficient_privileges, "Insufficient privileges", error_data)
|
||||
when "105"
|
||||
Util.error(:failed_to_add, "Failed to add user to group", error_data)
|
||||
end
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, Util.error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
end
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, Util.error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
end
|
||||
end
|
||||
|
||||
+47
-43
@@ -28,55 +28,59 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
module Storages::Peripherals::StorageInteraction::Nextcloud
|
||||
class GroupUsersQuery
|
||||
using Storages::Peripherals::ServiceResultRefinements
|
||||
module Storages
|
||||
module Peripherals
|
||||
module StorageInteraction
|
||||
module Nextcloud
|
||||
class GroupUsersQuery
|
||||
include Snitch
|
||||
using ServiceResultRefinements
|
||||
|
||||
def initialize(storage)
|
||||
@storage = storage
|
||||
@username = storage.username
|
||||
@password = storage.password
|
||||
end
|
||||
def self.call(storage:, group: storage.group)
|
||||
new(storage).call(group:)
|
||||
end
|
||||
|
||||
def self.call(storage:, group: storage.group)
|
||||
new(storage).call(group:)
|
||||
end
|
||||
def initialize(storage)
|
||||
@storage = storage
|
||||
@username = storage.username
|
||||
@password = storage.password
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def call(group:)
|
||||
response = OpenProject
|
||||
.httpx
|
||||
.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.get(
|
||||
Storages::UrlBuilder.url(
|
||||
@storage.uri,
|
||||
"ocs/v1.php/cloud/groups",
|
||||
CGI.escapeURIComponent(group)
|
||||
)
|
||||
)
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def call(group:)
|
||||
with_tagged_logger do
|
||||
url = UrlBuilder.url(@storage.uri, "ocs/v1.php/cloud/groups", CGI.escapeURIComponent(group))
|
||||
|
||||
error_data = Storages::StorageErrorData.new(source: self.class, payload: response)
|
||||
info "Requesting user list for group #{group} via url #{url} "
|
||||
response = OpenProject.httpx
|
||||
.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.get(url)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
group_users = Nokogiri::XML(response.body.to_s)
|
||||
.xpath("/ocs/data/users/element")
|
||||
.map(&:text)
|
||||
ServiceResult.success(result: group_users)
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
error_data = StorageErrorData.new(source: self.class, payload: response)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
group_users = Nokogiri::XML(response.body.to_s).xpath("/ocs/data/users/element").map(&:text)
|
||||
info "#{group_users.size} users found"
|
||||
ServiceResult.success(result: group_users)
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
end
|
||||
end
|
||||
|
||||
+61
-55
@@ -28,67 +28,73 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
module Storages::Peripherals::StorageInteraction::Nextcloud
|
||||
class RemoveUserFromGroupCommand
|
||||
def initialize(storage)
|
||||
@storage = storage
|
||||
@username = storage.username
|
||||
@password = storage.password
|
||||
@group = storage.group
|
||||
end
|
||||
module Storages
|
||||
module Peripherals
|
||||
module StorageInteraction
|
||||
module Nextcloud
|
||||
class RemoveUserFromGroupCommand
|
||||
include Snitch
|
||||
def self.call(storage:, user:, group: storage.group)
|
||||
new(storage).call(user:, group:)
|
||||
end
|
||||
|
||||
def self.call(storage:, user:, group: storage.group)
|
||||
new(storage).call(user:, group:)
|
||||
end
|
||||
def initialize(storage)
|
||||
@storage = storage
|
||||
@username = storage.username
|
||||
@password = storage.password
|
||||
@group = storage.group
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def call(user:, group: @group)
|
||||
response = OpenProject
|
||||
.httpx
|
||||
.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.delete(
|
||||
Storages::UrlBuilder.url(
|
||||
@storage.uri,
|
||||
"ocs/v1.php/cloud/users",
|
||||
user,
|
||||
"groups"
|
||||
) + "?groupid=#{CGI.escapeURIComponent(group)}"
|
||||
)
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def call(user:, group: @group)
|
||||
with_tagged_logger do
|
||||
url = UrlBuilder.url(@storage.uri, "ocs/v1.php/cloud/users", user, "groups") +
|
||||
"?groupid=#{CGI.escapeURIComponent(group)}"
|
||||
|
||||
error_data = Storages::StorageErrorData.new(source: self.class, payload: response)
|
||||
info "Removing #{user} from #{group} through #{url}"
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
statuscode = Nokogiri::XML(response.body.to_s).xpath("/ocs/meta/statuscode").text
|
||||
case statuscode
|
||||
when "100"
|
||||
ServiceResult.success(message: "User has been removed from group")
|
||||
when "101"
|
||||
Util.error(:error, "No group specified", error_data)
|
||||
when "102"
|
||||
Util.error(:error, "Group does not exist", error_data)
|
||||
when "103"
|
||||
Util.error(:error, "User does not exist", error_data)
|
||||
when "104"
|
||||
Util.error(:error, "Insufficient privileges", error_data)
|
||||
when "105"
|
||||
message = Nokogiri::XML(response.body).xpath("/ocs/meta/message").text
|
||||
Util.error(:error, "Failed to remove user #{user} from group #{group}: #{message}", error_data)
|
||||
response = OpenProject.httpx.basic_auth(@username, @password)
|
||||
.with(headers: { "OCS-APIRequest" => "true" })
|
||||
.delete(url)
|
||||
|
||||
error_data = StorageErrorData.new(source: self.class, payload: response)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
statuscode = Nokogiri::XML(response.body.to_s).xpath("/ocs/meta/statuscode").text
|
||||
case statuscode
|
||||
when "100"
|
||||
info "User has been removed from group"
|
||||
ServiceResult.success
|
||||
when "101"
|
||||
Util.error(:error, "No group specified", error_data)
|
||||
when "102"
|
||||
Util.error(:group_does_not_exist, "Group does not exist", error_data)
|
||||
when "103"
|
||||
Util.error(:user_does_not_exist, "User does not exist", error_data)
|
||||
when "104"
|
||||
Util.error(:insufficient_privileges, "Insufficient privileges", error_data)
|
||||
when "105"
|
||||
message = Nokogiri::XML(response.body).xpath("/ocs/meta/message").text
|
||||
Util.error(:failed_to_remove, message, error_data)
|
||||
end
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, Util.error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
end
|
||||
in { status: 405 }
|
||||
Util.error(:not_allowed, "Outbound request method not allowed", error_data)
|
||||
in { status: 401 }
|
||||
Util.error(:unauthorized, "Outbound request not authorized", error_data)
|
||||
in { status: 404 }
|
||||
Util.error(:not_found, "Outbound request destination not found", error_data)
|
||||
in { status: 409 }
|
||||
Util.error(:conflict, Util.error_text_from_response(response), error_data)
|
||||
else
|
||||
Util.error(:error, "Outbound request failed", error_data)
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
end
|
||||
end
|
||||
|
||||
+1
-8
@@ -33,6 +33,7 @@ module Storages
|
||||
module StorageInteraction
|
||||
module Nextcloud
|
||||
class SetPermissionsCommand
|
||||
include Snitch
|
||||
using ServiceResultRefinements
|
||||
|
||||
SUCCESS_XPATH = "/d:multistatus/d:response/d:propstat[d:status[text() = 'HTTP/1.1 200 OK']]/d:prop/nc:acl-list"
|
||||
@@ -125,14 +126,6 @@ module Storages
|
||||
end.to_xml
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def with_tagged_logger(&)
|
||||
Rails.logger.tagged(self.class, &)
|
||||
end
|
||||
|
||||
def info(message)
|
||||
Rails.logger.info message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
#++
|
||||
|
||||
module Storages
|
||||
module Snitch
|
||||
delegate :info, :error, to: :logger
|
||||
|
||||
def with_tagged_logger(tag = self.class, &)
|
||||
logger.tagged(*tag, &)
|
||||
end
|
||||
|
||||
def logger
|
||||
Rails.logger
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -31,7 +31,7 @@
|
||||
module Storages::Storages
|
||||
class NextcloudContract < ::ModelContract
|
||||
attribute :host
|
||||
validates :host, url: { message: I18n.t("activerecord.errors.messages.invalid_url") }, length: { maximum: 255 }
|
||||
validates :host, url: { message: :invalid_host_url }, length: { maximum: 255 }
|
||||
# Check that a host actually is a storage server.
|
||||
# But only do so if the validations above for URL were successful.
|
||||
validates :host, secure_context_uri: true, nextcloud_compatible_host: true, unless: -> { errors.include?(:host) }
|
||||
|
||||
+23
-22
@@ -32,6 +32,7 @@ module Storages
|
||||
class NextcloudGroupFolderPropertiesSyncService
|
||||
extend ActiveModel::Naming
|
||||
extend ActiveModel::Translation
|
||||
include Snitch
|
||||
|
||||
using Peripherals::ServiceResultRefinements
|
||||
|
||||
@@ -59,21 +60,27 @@ module Storages
|
||||
end
|
||||
|
||||
def call
|
||||
with_logging do
|
||||
with_tagged_logger([self.class, "storage-#{@storage.id}"]) do
|
||||
info "Starting AMPF Sync for Nextcloud Storage #{@storage.id}"
|
||||
prepare_remote_folders.on_failure { return @result }
|
||||
prepare_remote_folders.on_failure { return epilogue }
|
||||
apply_permissions_to_folders
|
||||
epilogue
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def epilogue
|
||||
info "Synchronization process for Nextcloud Storage #{@storage.id} has ended. #{@result.errors.count} errors found."
|
||||
@result
|
||||
end
|
||||
|
||||
# @param attribute [Symbol] attribute to which the error will be tied to
|
||||
# @param storage_error [Storages::StorageError] an StorageError instance
|
||||
# @param options [Hash<Symbol, Object>] optional extra parameters for the message generation
|
||||
# @return [ServiceResult]
|
||||
def add_error(attribute, storage_error, options: {})
|
||||
case storage_error
|
||||
case storage_error.code
|
||||
when :error, :unauthorized
|
||||
@result.errors.add(:base, storage_error.code, **options)
|
||||
else
|
||||
@@ -96,31 +103,35 @@ module Storages
|
||||
end
|
||||
|
||||
def apply_permissions_to_folders
|
||||
info "Setting permissions to project folders"
|
||||
remote_admins = admin_client_tokens_scope.pluck(:origin_user_id)
|
||||
|
||||
active_project_storages_scope.where.not(project_folder_id: nil).find_each do |project_storage|
|
||||
set_folders_permissions(remote_admins, project_storage)
|
||||
end
|
||||
|
||||
add_remove_users_to_group
|
||||
info "Updating user access on automatically managed project folders"
|
||||
add_remove_users_to_group(@storage.group, @storage.username)
|
||||
|
||||
ServiceResult.success
|
||||
end
|
||||
|
||||
def add_remove_users_to_group
|
||||
def add_remove_users_to_group(group, username)
|
||||
remote_users = remote_group_users.result_or do |error|
|
||||
return format_and_log_error(error, group: @storage.group)
|
||||
format_and_log_error(error, group:)
|
||||
return add_error(:remote_group_users, error, options: { group: }).fail!
|
||||
end
|
||||
|
||||
local_users = client_tokens_scope.order(:id).pluck(:origin_user_id)
|
||||
|
||||
remove_users_from_remote_group(remote_users - local_users - [@storage.username])
|
||||
add_users_to_remote_group(local_users - remote_users - [@storage.username])
|
||||
remove_users_from_remote_group(remote_users - local_users - [username])
|
||||
add_users_to_remote_group(local_users - remote_users - [username])
|
||||
end
|
||||
|
||||
def add_users_to_remote_group(users_to_add)
|
||||
users_to_add.each do |user|
|
||||
add_user_to_group.call(storage: @storage, user:).error_and do |error|
|
||||
add_error(:add_user_to_group, error, options: { user:, group: @storage.group, reason: error.log_message })
|
||||
format_and_log_error(error, group: @storage.group, user:)
|
||||
end
|
||||
end
|
||||
@@ -129,6 +140,7 @@ module Storages
|
||||
def remove_users_from_remote_group(users_to_remove)
|
||||
users_to_remove.each do |user|
|
||||
remove_user_from_group.call(storage: @storage, user:).error_and do |error|
|
||||
add_error(:remove_user_from_group, error, options: { user:, group: @storage.group, reason: error.log_message })
|
||||
format_and_log_error(error, group: @storage.group, user:)
|
||||
end
|
||||
end
|
||||
@@ -288,6 +300,7 @@ module Storages
|
||||
end
|
||||
|
||||
def remote_group_users
|
||||
info "Retrieving users that a part of the #{@storage.group} group"
|
||||
group_users.call(storage: @storage, group: @storage.group)
|
||||
end
|
||||
|
||||
@@ -321,20 +334,8 @@ module Storages
|
||||
payload.to_s
|
||||
end
|
||||
|
||||
error_message = context.merge({ command: error.data.source, message: error.log_message, data: })
|
||||
logger.error error_message
|
||||
end
|
||||
|
||||
def info(message)
|
||||
logger.info(message)
|
||||
end
|
||||
|
||||
def with_logging(&)
|
||||
logger.tagged(self.class, "storage-#{@storage.id}", &)
|
||||
end
|
||||
|
||||
def logger
|
||||
Rails.logger
|
||||
error_message = context.merge({ error_code: error.code, data: })
|
||||
error error_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
---
|
||||
en:
|
||||
services:
|
||||
attributes:
|
||||
storages/nextcloud_group_folder_properties_sync_service:
|
||||
remote_folders: 'Reading contents of the group folder:'
|
||||
ensure_root_folder_permissions: 'Setting Basic Permissions:'
|
||||
create_folder: 'Managed Project Folder Creation:'
|
||||
rename_project_folder: 'Renaming managed project Folder:'
|
||||
hide_inactive_folders: 'Hide Inactive Folders Step:'
|
||||
errors:
|
||||
models:
|
||||
storages/nextcloud_group_folder_properties_sync_service:
|
||||
unauthorized: "OpenProject could not sync with Nextcloud. Please check you storage and Nextcloud configuration"
|
||||
error: "An unexpected error occurred. Please ensure that you Nextcloud instance is reachable and check OpenProject worker logs for more information"
|
||||
attributes:
|
||||
remote_folders:
|
||||
not_found: "%{group_folder} wasn't found. Please check your Nextcloud setup."
|
||||
not_allowed: "The %{username} doesn't have access to the %{group_folder}. Please check the folder permissions on Nextcloud"
|
||||
|
||||
activerecord:
|
||||
attributes:
|
||||
storages/file_link:
|
||||
@@ -31,8 +13,8 @@ en:
|
||||
tenant: Directory (tenant) ID
|
||||
errors:
|
||||
messages:
|
||||
invalid_host_url: is not a valid URL.
|
||||
not_linked_to_project: is not linked to project.
|
||||
invalid_url: is not a valid URL.
|
||||
models:
|
||||
storages/file_link:
|
||||
attributes:
|
||||
@@ -87,6 +69,26 @@ en:
|
||||
heading: Remove project from %{storage_type}
|
||||
text: This action is irreversible and will remove all links from work packages of this project to files and folders of that storage.
|
||||
label: Remove project
|
||||
services:
|
||||
attributes:
|
||||
storages/nextcloud_group_folder_properties_sync_service:
|
||||
create_folder: 'Managed Project Folder Creation:'
|
||||
ensure_root_folder_permissions: 'Setting Basic Permissions:'
|
||||
hide_inactive_folders: 'Hide Inactive Folders Step:'
|
||||
remote_folders: 'Reading contents of the group folder:'
|
||||
remove_user_from_group: 'Revoke User from Group:'
|
||||
rename_project_folder: 'Renaming managed project Folder:'
|
||||
errors:
|
||||
models:
|
||||
storages/nextcloud_group_folder_properties_sync_service:
|
||||
attributes:
|
||||
remote_folders:
|
||||
not_allowed: The %{username} doesn't have access to the %{group_folder}. Please check the folder permissions on Nextcloud
|
||||
not_found: "%{group_folder} wasn't found. Please check your Nextcloud setup."
|
||||
remove_user_from_group:
|
||||
failed_to_remove: 'The user %{user} could not be removed from the %{group} group for the following reason: %{reason}'
|
||||
error: An unexpected error occurred. Please ensure that you Nextcloud instance is reachable and check OpenProject worker logs for more information
|
||||
unauthorized: OpenProject could not sync with Nextcloud. Please check you storage and Nextcloud configuration
|
||||
storages:
|
||||
buttons:
|
||||
complete_without_setup: Complete without it
|
||||
|
||||
@@ -144,7 +144,6 @@ RSpec.describe Storages::Peripherals::Registry, :webmock do
|
||||
it "adds user to the group" do
|
||||
result = registry.resolve("nextcloud.commands.add_user_to_group").call(storage:, user: origin_user_id)
|
||||
expect(result).to be_success
|
||||
expect(result.message).to eq("User has been added successfully")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -186,7 +185,6 @@ RSpec.describe Storages::Peripherals::Registry, :webmock do
|
||||
it "removes user from the group" do
|
||||
result = registry.resolve("nextcloud.commands.remove_user_from_group").call(storage:, user: origin_user_id)
|
||||
expect(result).to be_success
|
||||
expect(result.message).to eq("User has been removed from group")
|
||||
end
|
||||
|
||||
context "when Nextcloud reponds with 105 code in the response body" do
|
||||
@@ -210,8 +208,7 @@ RSpec.describe Storages::Peripherals::Registry, :webmock do
|
||||
result = registry.resolve("nextcloud.commands.remove_user_from_group").call(storage:, user: origin_user_id)
|
||||
expect(result).to be_failure
|
||||
expect(result.errors.log_message)
|
||||
.to eq("Failed to remove user #{origin_user_id} from group OpenProject: " \
|
||||
"Not viable to remove user from the last group you are SubAdmin of")
|
||||
.to eq("Not viable to remove user from the last group you are SubAdmin of")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,13 +116,13 @@ RSpec.shared_examples_for "nextcloud storage contract", :storage_server_helpers,
|
||||
context "as host is not a URL" do
|
||||
let(:storage_host) { "---invalid-url---" }
|
||||
|
||||
include_examples "contract is invalid", host: I18n.t("activerecord.errors.messages.invalid_url")
|
||||
include_examples "contract is invalid", host: :invalid_host_url
|
||||
end
|
||||
|
||||
context "as host is an empty string" do
|
||||
let(:storage_host) { "" }
|
||||
|
||||
include_examples "contract is invalid", host: I18n.t("activerecord.errors.messages.invalid_url")
|
||||
include_examples "contract is invalid", host: :invalid_host_url
|
||||
end
|
||||
|
||||
context "as host is longer than 255" do
|
||||
|
||||
@@ -178,7 +178,7 @@ RSpec.describe "API v3 storages resource", :webmock, content_type: :json do
|
||||
end
|
||||
|
||||
it_behaves_like "constraint violation" do
|
||||
let(:message) { "Host is not a valid URL" }
|
||||
let(:message) { "Host is not a valid URL." }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+9
-21
@@ -691,10 +691,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(folder: "OpenProject",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::Internal::PropfindQueryLegacy,
|
||||
message: "Outbound request destination not found",
|
||||
data: { status: 404, body: "" })
|
||||
.with(folder: "OpenProject", error_code: :not_found, data: { status: 404, body: "" })
|
||||
end
|
||||
|
||||
it "returns a failure" do
|
||||
@@ -758,8 +755,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(folder: "OpenProject",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::SetPermissionsCommand,
|
||||
message: "Outbound request not authorized",
|
||||
error_code: :unauthorized,
|
||||
data: { status: 401, body: "Heute nicht" })
|
||||
end
|
||||
|
||||
@@ -767,8 +763,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
result = described_class.new(storage).call
|
||||
|
||||
expect(result).to be_failure
|
||||
expect(result.errors[:ensure_root_folder_permissions])
|
||||
.to contain_exactly(I18n.t("#{prefix}.unauthorized"))
|
||||
expect(result.errors[:base]).to contain_exactly(I18n.t("#{prefix}.unauthorized"))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -804,8 +799,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(folder_name: "/OpenProject/[Sample] Project Name | Ehuu (#{project1.id})/",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::CreateFolderCommand,
|
||||
message: "Outbound request destination not found!",
|
||||
error_code: :not_found,
|
||||
data: "not found")
|
||||
end
|
||||
end
|
||||
@@ -834,9 +828,8 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(folder_id: project_storage2.project_folder_id,
|
||||
error_code: :not_found,
|
||||
folder_name: "Jedi Project Folder ||| (#{project2.id})",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::RenameFileCommand,
|
||||
message: "Outbound request destination not found",
|
||||
data: { status: 404, body: "" })
|
||||
end
|
||||
end
|
||||
@@ -867,8 +860,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
.to have_received(:error)
|
||||
.with(context: "hide_folder",
|
||||
folder: "/OpenProject/Lost Jedi Project Folder #2/",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::SetPermissionsCommand,
|
||||
message: "Outbound request failed",
|
||||
error_code: :error,
|
||||
data: { status: 500, body: "A server error occurred" })
|
||||
end
|
||||
end
|
||||
@@ -898,8 +890,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
expect(Rails.logger)
|
||||
.to have_received(:error)
|
||||
.with(folder: "/OpenProject/Jedi Project Folder ||| (#{project2.id})/",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::SetPermissionsCommand,
|
||||
message: "Outbound request failed",
|
||||
error_code: :error,
|
||||
data: { status: 500, body: "Divide by cucumber error. Please reinstall universe and reboot." })
|
||||
end
|
||||
end
|
||||
@@ -930,8 +921,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
.to have_received(:error)
|
||||
.with(group: "OpenProject",
|
||||
user: "Obi-Wan",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::AddUserToGroupCommand,
|
||||
message: "Outbound request failed",
|
||||
error_code: :error,
|
||||
data: { status: 302, body: "" })
|
||||
end
|
||||
end
|
||||
@@ -965,9 +955,7 @@ RSpec.describe Storages::NextcloudGroupFolderPropertiesSyncService, :webmock do
|
||||
.to have_received(:error)
|
||||
.with(group: "OpenProject",
|
||||
user: "Darth Maul",
|
||||
command: Storages::Peripherals::StorageInteraction::Nextcloud::RemoveUserFromGroupCommand,
|
||||
message: "Failed to remove user Darth Maul from group OpenProject: " \
|
||||
"Not viable to remove user from the last group you are SubAdmin of",
|
||||
error_code: :failed_to_remove,
|
||||
data: { status: 200, body: remove_user_from_group_response })
|
||||
end
|
||||
end
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ RSpec.describe Storages::AutomaticallyManagedStorageSyncJob, type: :job do
|
||||
allow(job).to receive(:perform_later)
|
||||
|
||||
errors = ActiveModel::Errors.new(Storages::NextcloudGroupFolderPropertiesSyncService.new(managed_nextcloud))
|
||||
errors.add(:group_folder, :not_found, group_folder: managed_nextcloud.group_folder)
|
||||
errors.add(:remote_folders, :not_found, group_folder: managed_nextcloud.group_folder)
|
||||
|
||||
allow(Storages::NextcloudGroupFolderPropertiesSyncService)
|
||||
.to receive(:call)
|
||||
|
||||
Reference in New Issue
Block a user