Skip to content

Commit cc5a931

Browse files
Sad-liesalsabeeljamalFaheemvc
authored
feat: file repository (wraft#160)
* feat: implement integration management system - Refactor vault utility to CloakVault for encryption. - Introduce EncryptedMapType for storing encrypted map data. - Add Integration and IntegrationConfig modules for managing external service integrations. - Implement API endpoints for integration management, including listing, creating, enabling, and disabling integrations. - Create views and controllers for integration configuration and management. - Add migration for integrations table and update permissions for integration actions. --------- Co-authored-by: Salsabeel <[email protected]> Co-authored-by: Faheem vc <[email protected]>
1 parent 2e3f14b commit cc5a931

74 files changed

Lines changed: 5114 additions & 1640 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/config.exs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,30 @@ config :wraft_doc, :phoenix_swagger,
7070
# Cron jobs Overview https://github.com/sorentwo/oban#periodic-jobs
7171
config :wraft_doc, Oban,
7272
repo: WraftDoc.Repo,
73-
queues: [default: 10, events: 50, media: 20, mailer: 20, scheduled: 10, webhooks: 15],
73+
queues: [
74+
default: 10,
75+
events: 50,
76+
media: 20,
77+
mailer: 20,
78+
scheduled: 10,
79+
webhooks: 15,
80+
cloud_provider: 15,
81+
integrations: 15,
82+
repository: 15
83+
],
7484
plugins: [
7585
Oban.Plugins.Pruner,
7686
{Oban.Plugins.Lifeline, rescue_after: :timer.minutes(5)},
7787
{Oban.Plugins.Cron,
7888
crontab: [
7989
# {"0 0 * * MON", WraftDoc.Workers.ScheduledWorker,
8090
# queue: :scheduled, tags: ["unused_assets"]},
91+
{"0 3 * * *", WraftDoc.Workers.RepositoryWorker,
92+
queue: :repository,
93+
tags: ["repository_size_update"],
94+
args: %{"action" => "update_repo_size"}},
8195
{"0 0 * * *", WraftDoc.Workers.ReminderWorker, queue: :scheduled, tags: ["reminders"]},
96+
{"*/5 * * * *", WraftDoc.Workers.TokenRefreshWorker},
8297
{"@weekly", WraftDoc.Workers.ScheduledWorker,
8398
queue: :scheduled,
8499
tags: ["hard_delete_organisation_records"],
@@ -90,7 +105,8 @@ config :wraft_doc, Oban,
90105

91106
# File Upload config
92107
config :waffle,
93-
storage: Waffle.Storage.S3
108+
storage: Waffle.Storage.S3,
109+
version_timeout: 30_000
94110

95111
config :ex_aws,
96112
json_codec: Jason,

lib/wraft_doc/application.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ defmodule WraftDoc.Application do
3131
# restart: :permanent
3232
# )
3333
WraftDoc.Schedulers.RefreshDashboardStats,
34-
WraftDoc.Utils.Vault
34+
WraftDoc.Utils.CloakVault,
35+
{Registry, keys: :unique, name: WraftDoc.TokenRegistry},
36+
{DynamicSupervisor, strategy: :one_for_one, name: WraftDoc.TokenSupervisor}
3537
]
3638

3739
# See https://hexdocs.pm/elixir/Supervisor.html

lib/wraft_doc/client/minio.ex

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,75 @@ defmodule WraftDoc.Client.Minio do
175175
end
176176
end
177177

178+
@doc """
179+
Check if a prefix exists in MinIO.
180+
"""
181+
@spec prefix_exists?(String.t()) :: boolean()
182+
def prefix_exists?(prefix) do
183+
bucket()
184+
|> S3.list_objects(prefix: prefix, max_keys: 1)
185+
|> @ex_aws_module.request()
186+
|> case do
187+
{:ok, %{body: %{contents: []}}} -> false
188+
{:ok, %{body: %{contents: _}}} -> true
189+
_ -> false
190+
end
191+
end
192+
193+
@doc """
194+
Renames a single file in MinIO (copy + delete).
195+
Returns {:ok, new_path} on success.
196+
"""
197+
@spec rename_file(String.t(), String.t()) :: ex_aws_response()
198+
def rename_file(old_path, new_path) do
199+
with {:ok, _} <- copy_files(new_path, old_path),
200+
{:ok, _} <- delete_file(old_path) do
201+
{:ok, new_path}
202+
else
203+
{:error, reason} -> {:error, reason}
204+
end
205+
end
206+
207+
@doc """
208+
Renames a folder (prefix) and all files under it.
209+
- Copies all objects from old_prefix -> new_prefix.
210+
- Deletes the old ones after successful copy.
211+
212+
Example:
213+
rename_folder("organisations/123/old/", "organisations/123/new/")
214+
"""
215+
@spec rename_folder(String.t(), String.t()) :: :ok | {:error, any()}
216+
def rename_folder(old_prefix, new_prefix) do
217+
old_prefix = String.trim_trailing(old_prefix, "/") <> "/"
218+
new_prefix = String.trim_trailing(new_prefix, "/") <> "/"
219+
220+
if prefix_exists?(old_prefix) do
221+
bucket()
222+
|> S3.list_objects_v2(prefix: old_prefix)
223+
|> @ex_aws_module.stream!()
224+
|> Task.async_stream(
225+
fn %{key: old_key} ->
226+
new_key = String.replace_prefix(old_key, old_prefix, new_prefix)
227+
228+
with {:ok, _} <- copy_files(new_key, old_key),
229+
{:ok, _} <- delete_files(old_key) do
230+
{:ok, new_key}
231+
else
232+
{:error, reason} ->
233+
Logger.error("Failed to rename #{old_key}: #{inspect(reason)}")
234+
{:error, reason}
235+
end
236+
end,
237+
max_concurrency: 5,
238+
timeout: :infinity
239+
)
240+
|> Enum.reduce_while(:ok, fn
241+
{:ok, {:ok, _}}, acc -> {:cont, acc}
242+
{:ok, {:error, reason}}, _ -> {:halt, {:error, reason}}
243+
{:exit, reason}, _ -> {:halt, {:error, reason}}
244+
end)
245+
end
246+
end
247+
178248
defp bucket, do: System.get_env("MINIO_BUCKET")
179249
end

0 commit comments

Comments
 (0)