aven 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +8 -0
- data/app/assets/stylesheets/aven/application.css +14 -0
- data/app/assets/stylesheets/aven/application.tailwind.css +7 -0
- data/app/assets/stylesheets/aven/tailwind.css +224 -0
- data/app/components/aven/application_view_component.rb +15 -0
- data/app/components/aven/views/admin/dashboard/index/component.html.erb +1 -0
- data/app/components/aven/views/admin/dashboard/index/component.rb +5 -0
- data/app/components/aven/views/static/index/component.html.erb +17 -0
- data/app/components/aven/views/static/index/component.rb +5 -0
- data/app/components/aven/views/static/index/controller.js +7 -0
- data/app/controllers/aven/admin/base.rb +16 -0
- data/app/controllers/aven/admin/dashboard_controller.rb +9 -0
- data/app/controllers/aven/application_controller.rb +5 -0
- data/app/controllers/aven/auth_controller.rb +64 -0
- data/app/controllers/aven/static_controller.rb +7 -0
- data/app/helpers/aven/application_helper.rb +20 -0
- data/app/javascript/sqema/application.js +3 -0
- data/app/javascript/sqema/controllers/application.js +5 -0
- data/app/javascript/sqema/controllers/index.js +11 -0
- data/app/jobs/aven/application_job.rb +4 -0
- data/app/mailers/aven/application_mailer.rb +6 -0
- data/app/models/aven/app_record.rb +76 -0
- data/app/models/aven/app_record_schema.rb +47 -0
- data/app/models/aven/application_record.rb +5 -0
- data/app/models/aven/log.rb +67 -0
- data/app/models/aven/loggable.rb +21 -0
- data/app/models/aven/user.rb +63 -0
- data/app/models/aven/workspace.rb +39 -0
- data/app/models/aven/workspace_role.rb +47 -0
- data/app/models/aven/workspace_user.rb +55 -0
- data/app/models/aven/workspace_user_role.rb +39 -0
- data/app/views/layouts/aven/admin.html.erb +16 -0
- data/app/views/layouts/aven/application.html.erb +18 -0
- data/config/importmap.rb +16 -0
- data/config/initializers/devise.rb +43 -0
- data/config/routes.rb +16 -0
- data/db/migrate/20251003090752_create_aven_users.rb +19 -0
- data/db/migrate/20251004182000_create_aven_workspaces.rb +14 -0
- data/db/migrate/20251004182010_create_aven_workspace_users.rb +12 -0
- data/db/migrate/20251004182020_create_aven_workspace_roles.rb +13 -0
- data/db/migrate/20251004182030_create_aven_workspace_user_roles.rb +12 -0
- data/db/migrate/20251004190000_create_aven_logs.rb +22 -0
- data/db/migrate/20251004190100_create_aven_app_record_schemas.rb +12 -0
- data/db/migrate/20251004190110_create_aven_app_records.rb +12 -0
- data/lib/aven/configuration.rb +35 -0
- data/lib/aven/engine.rb +44 -0
- data/lib/aven/version.rb +3 -0
- data/lib/aven.rb +6 -0
- data/lib/tasks/annotate_rb.rake +10 -0
- data/lib/tasks/sqema_tasks.rake +21 -0
- metadata +321 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_logs
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# level :string default("info"), not null
|
7
|
+
# loggable_type :string not null
|
8
|
+
# message :text not null
|
9
|
+
# metadata :jsonb
|
10
|
+
# state :string
|
11
|
+
# state_machine :string
|
12
|
+
# created_at :datetime not null
|
13
|
+
# updated_at :datetime not null
|
14
|
+
# loggable_id :bigint not null
|
15
|
+
# run_id :string
|
16
|
+
# workspace_id :bigint not null
|
17
|
+
#
|
18
|
+
# Indexes
|
19
|
+
#
|
20
|
+
# idx_aven_logs_on_loggable_run_state_created_at (loggable_type,loggable_id,run_id,state,created_at)
|
21
|
+
# index_aven_logs_on_created_at (created_at)
|
22
|
+
# index_aven_logs_on_level (level)
|
23
|
+
# index_aven_logs_on_loggable (loggable_type,loggable_id)
|
24
|
+
# index_aven_logs_on_workspace_id (workspace_id)
|
25
|
+
#
|
26
|
+
# Foreign Keys
|
27
|
+
#
|
28
|
+
# fk_rails_... (workspace_id => aven_workspaces.id)
|
29
|
+
#
|
30
|
+
module Aven
|
31
|
+
class Log < ApplicationRecord
|
32
|
+
self.table_name = "aven_logs"
|
33
|
+
|
34
|
+
LEVELS = %w[debug info warn error fatal].freeze
|
35
|
+
|
36
|
+
belongs_to :loggable, polymorphic: true
|
37
|
+
belongs_to :workspace, class_name: "Aven::Workspace"
|
38
|
+
|
39
|
+
validates :message, presence: true
|
40
|
+
validates :level, inclusion: { in: LEVELS }
|
41
|
+
|
42
|
+
scope :by_level, ->(level) { where(level:) }
|
43
|
+
scope :recent, -> { order(created_at: :desc) }
|
44
|
+
|
45
|
+
before_validation :apply_loggable_context
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def apply_loggable_context
|
50
|
+
owner = loggable
|
51
|
+
return unless owner
|
52
|
+
|
53
|
+
if respond_to?(:workspace_id) && workspace_id.blank?
|
54
|
+
if owner.is_a?(Aven::Workspace)
|
55
|
+
self.workspace = owner
|
56
|
+
elsif owner.respond_to?(:workspace)
|
57
|
+
self.workspace = owner.workspace
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if respond_to?(:run_id) && run_id.blank? && owner.respond_to?(:_log_run_id)
|
62
|
+
self.run_id = owner._log_run_id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Aven
|
2
|
+
module Loggable
|
3
|
+
def log!(message:, level: "info", metadata: nil, **extra)
|
4
|
+
attrs = {
|
5
|
+
message: message,
|
6
|
+
level: level,
|
7
|
+
metadata: metadata || {}
|
8
|
+
}
|
9
|
+
|
10
|
+
ws = is_a?(Aven::Workspace) ? self : workspace
|
11
|
+
attrs[:workspace] = ws
|
12
|
+
|
13
|
+
attrs[:run_id] = extra[:run_id] if extra.key?(:run_id)
|
14
|
+
attrs[:state] = extra[:state] if extra.key?(:state)
|
15
|
+
attrs[:state_machine] = extra[:state_machine] if extra.key?(:state_machine)
|
16
|
+
|
17
|
+
logs.create!(attrs)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_users
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# access_token :string
|
7
|
+
# admin :boolean default(FALSE), not null
|
8
|
+
# auth_tenant :string
|
9
|
+
# email :string default(""), not null
|
10
|
+
# encrypted_password :string default(""), not null
|
11
|
+
# remember_created_at :datetime
|
12
|
+
# reset_password_sent_at :datetime
|
13
|
+
# reset_password_token :string
|
14
|
+
# created_at :datetime not null
|
15
|
+
# updated_at :datetime not null
|
16
|
+
# remote_id :string
|
17
|
+
#
|
18
|
+
# Indexes
|
19
|
+
#
|
20
|
+
# index_aven_users_on_email_and_auth_tenant (email,auth_tenant) UNIQUE
|
21
|
+
# index_aven_users_on_reset_password_token (reset_password_token) UNIQUE
|
22
|
+
#
|
23
|
+
module Aven
|
24
|
+
class User < ApplicationRecord
|
25
|
+
devise(
|
26
|
+
:omniauthable,
|
27
|
+
omniauth_providers: Aven.configuration.auth.providers.map { |p| p[:provider] }
|
28
|
+
)
|
29
|
+
|
30
|
+
has_many :workspace_users, dependent: :destroy
|
31
|
+
has_many :workspaces, through: :workspace_users
|
32
|
+
has_many :workspace_user_roles, through: :workspace_users
|
33
|
+
has_many :workspace_roles, through: :workspace_user_roles
|
34
|
+
|
35
|
+
# has_many(:repos, class_name: UserRepo.name)
|
36
|
+
# has_many(:deployments)
|
37
|
+
# has_many(:strategies, foreign_key: :author_id, inverse_of: :author)
|
38
|
+
# has_many(:credentials, class_name: ProviderCredential.name)
|
39
|
+
|
40
|
+
validates :email, presence: true, uniqueness: { scope: :auth_tenant, case_sensitive: false }, format: { with: URI::MailTo::EMAIL_REGEXP }
|
41
|
+
validates :remote_id, uniqueness: { scope: :auth_tenant, case_sensitive: false }, allow_blank: true
|
42
|
+
|
43
|
+
encrypts(:access_token)
|
44
|
+
|
45
|
+
def self.create_from_omniauth!(request_env, auth_tenant)
|
46
|
+
user = request_env.dig("omniauth.auth")
|
47
|
+
remote_id = user["uid"]
|
48
|
+
email = user.dig("info", "email") || "#{SecureRandom.uuid}@aven.dev"
|
49
|
+
|
50
|
+
u = where(auth_tenant:, remote_id:).or(
|
51
|
+
where(auth_tenant:, email:)
|
52
|
+
).first_or_initialize
|
53
|
+
|
54
|
+
u.auth_tenant = auth_tenant
|
55
|
+
u.remote_id = remote_id
|
56
|
+
u.email = email
|
57
|
+
u.access_token = user.dig("credentials", "token")
|
58
|
+
u.save!
|
59
|
+
|
60
|
+
u
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_workspaces
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# description :text
|
7
|
+
# domain :string
|
8
|
+
# label :string
|
9
|
+
# slug :string
|
10
|
+
# created_at :datetime not null
|
11
|
+
# updated_at :datetime not null
|
12
|
+
#
|
13
|
+
# Indexes
|
14
|
+
#
|
15
|
+
# index_aven_workspaces_on_slug (slug) UNIQUE
|
16
|
+
#
|
17
|
+
module Aven
|
18
|
+
class Workspace < ApplicationRecord
|
19
|
+
self.table_name = "aven_workspaces"
|
20
|
+
|
21
|
+
has_many :workspace_users, class_name: "Aven::WorkspaceUser", dependent: :destroy
|
22
|
+
has_many :users, through: :workspace_users, class_name: "Aven::User"
|
23
|
+
has_many :workspace_roles, class_name: "Aven::WorkspaceRole", dependent: :destroy
|
24
|
+
has_many :workspace_user_roles, through: :workspace_roles, class_name: "Aven::WorkspaceUserRole"
|
25
|
+
|
26
|
+
validates :slug, uniqueness: true, allow_blank: true
|
27
|
+
validates :label, length: { maximum: 255 }, allow_blank: true
|
28
|
+
validates :description, length: { maximum: 1000 }, allow_blank: true
|
29
|
+
|
30
|
+
before_validation :generate_slug, if: -> { slug.blank? && label.present? }
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def generate_slug
|
35
|
+
self.slug = label.parameterize if label.present?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_workspace_roles
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# description :string
|
7
|
+
# label :string not null
|
8
|
+
# created_at :datetime not null
|
9
|
+
# updated_at :datetime not null
|
10
|
+
# workspace_id :bigint
|
11
|
+
#
|
12
|
+
# Indexes
|
13
|
+
#
|
14
|
+
# idx_aven_workspace_roles_on_ws_label (workspace_id,label) UNIQUE
|
15
|
+
# index_aven_workspace_roles_on_workspace_id (workspace_id)
|
16
|
+
#
|
17
|
+
# Foreign Keys
|
18
|
+
#
|
19
|
+
# fk_rails_... (workspace_id => aven_workspaces.id)
|
20
|
+
#
|
21
|
+
module Aven
|
22
|
+
class WorkspaceRole < ApplicationRecord
|
23
|
+
self.table_name = "aven_workspace_roles"
|
24
|
+
|
25
|
+
belongs_to :workspace, class_name: "Aven::Workspace"
|
26
|
+
has_many :workspace_user_roles, class_name: "Aven::WorkspaceUserRole", dependent: :destroy
|
27
|
+
has_many :workspace_users, through: :workspace_user_roles, class_name: "Aven::WorkspaceUser"
|
28
|
+
has_many :users, through: :workspace_users, class_name: "Aven::User"
|
29
|
+
|
30
|
+
validates :label, presence: true
|
31
|
+
validates :label, uniqueness: { scope: :workspace_id }
|
32
|
+
|
33
|
+
PREDEFINED_ROLES = %w[owner admin member viewer].freeze
|
34
|
+
|
35
|
+
scope :predefined, -> { where(label: PREDEFINED_ROLES) }
|
36
|
+
scope :custom, -> { where.not(label: PREDEFINED_ROLES) }
|
37
|
+
|
38
|
+
def predefined?
|
39
|
+
PREDEFINED_ROLES.include?(label)
|
40
|
+
end
|
41
|
+
|
42
|
+
def custom?
|
43
|
+
!predefined?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_workspace_users
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# created_at :datetime not null
|
7
|
+
# updated_at :datetime not null
|
8
|
+
# user_id :bigint not null
|
9
|
+
# workspace_id :bigint not null
|
10
|
+
#
|
11
|
+
# Indexes
|
12
|
+
#
|
13
|
+
# idx_aven_workspace_users_on_user_workspace (user_id,workspace_id) UNIQUE
|
14
|
+
# index_aven_workspace_users_on_user_id (user_id)
|
15
|
+
# index_aven_workspace_users_on_workspace_id (workspace_id)
|
16
|
+
#
|
17
|
+
# Foreign Keys
|
18
|
+
#
|
19
|
+
# fk_rails_... (user_id => aven_users.id)
|
20
|
+
# fk_rails_... (workspace_id => aven_workspaces.id)
|
21
|
+
#
|
22
|
+
module Aven
|
23
|
+
class WorkspaceUser < ApplicationRecord
|
24
|
+
self.table_name = "aven_workspace_users"
|
25
|
+
|
26
|
+
belongs_to :user, class_name: "Aven::User"
|
27
|
+
belongs_to :workspace, class_name: "Aven::Workspace"
|
28
|
+
|
29
|
+
has_many :workspace_user_roles, class_name: "Aven::WorkspaceUserRole", dependent: :destroy
|
30
|
+
has_many :workspace_roles, through: :workspace_user_roles, class_name: "Aven::WorkspaceRole"
|
31
|
+
|
32
|
+
validates :user_id, uniqueness: { scope: :workspace_id }
|
33
|
+
|
34
|
+
def roles
|
35
|
+
workspace_roles.pluck(:label)
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_role?(role_label)
|
39
|
+
workspace_roles.exists?(label: role_label)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_role(role_label)
|
43
|
+
role = workspace.workspace_roles.find_or_create_by!(label: role_label)
|
44
|
+
workspace_user_roles.find_or_create_by!(workspace_role: role)
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_role(role_label)
|
48
|
+
role = workspace.workspace_roles.find_by(label: role_label)
|
49
|
+
return unless role
|
50
|
+
|
51
|
+
workspace_user_roles.where(workspace_role: role).destroy_all
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: aven_workspace_user_roles
|
4
|
+
#
|
5
|
+
# id :bigint not null, primary key
|
6
|
+
# created_at :datetime not null
|
7
|
+
# updated_at :datetime not null
|
8
|
+
# workspace_role_id :bigint
|
9
|
+
# workspace_user_id :bigint
|
10
|
+
#
|
11
|
+
# Indexes
|
12
|
+
#
|
13
|
+
# idx_aven_ws_user_roles_on_role_user (workspace_role_id,workspace_user_id) UNIQUE
|
14
|
+
# index_aven_workspace_user_roles_on_workspace_role_id (workspace_role_id)
|
15
|
+
# index_aven_workspace_user_roles_on_workspace_user_id (workspace_user_id)
|
16
|
+
#
|
17
|
+
# Foreign Keys
|
18
|
+
#
|
19
|
+
# fk_rails_... (workspace_role_id => aven_workspace_roles.id)
|
20
|
+
# fk_rails_... (workspace_user_id => aven_workspace_users.id)
|
21
|
+
#
|
22
|
+
module Aven
|
23
|
+
class WorkspaceUserRole < ApplicationRecord
|
24
|
+
self.table_name = "aven_workspace_user_roles"
|
25
|
+
|
26
|
+
belongs_to :workspace_user, class_name: "Aven::WorkspaceUser"
|
27
|
+
belongs_to :workspace_role, class_name: "Aven::WorkspaceRole"
|
28
|
+
|
29
|
+
validates :workspace_user_id, uniqueness: { scope: :workspace_role_id }
|
30
|
+
|
31
|
+
delegate :workspace, :label, :description, to: :workspace_role
|
32
|
+
delegate :user, to: :workspace_user
|
33
|
+
delegate :email, :username, to: :user
|
34
|
+
|
35
|
+
scope :for_workspace, ->(workspace) { joins(:workspace_role).where(aven_workspace_roles: { workspace_id: workspace.id }) }
|
36
|
+
scope :with_role, ->(role_label) { joins(:workspace_role).where(aven_workspace_roles: { label: role_label }) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html class='bg-slate-50'>
|
3
|
+
<head>
|
4
|
+
<title>Aven</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<%= yield :head %>
|
8
|
+
<script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script>
|
9
|
+
<%= stylesheet_link_tag "aven/application", media: "all" %>
|
10
|
+
<%= stylesheet_link_tag "aven/tailwind", media: "all" %>
|
11
|
+
<%= javascript_importmap_tags "aven/application", importmap: Aven.importmap %>
|
12
|
+
</head>
|
13
|
+
<body class='bg-slate-100'>
|
14
|
+
<%= yield %>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Aven</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
<%= yield :head %>
|
8
|
+
<script src="https://cdn.jsdelivr.net/npm/@tailwindplus/elements@1" type="module"></script>
|
9
|
+
<%= stylesheet_link_tag "aeros/application", media: "all" %>
|
10
|
+
<%= stylesheet_link_tag "aeros/tailwind", media: "all" %>
|
11
|
+
<%= stylesheet_link_tag "aven/application", media: "all" %>
|
12
|
+
<%= stylesheet_link_tag "aven/tailwind", media: "all" %>
|
13
|
+
<%= javascript_importmap_tags "aven/application", importmap: Aven.importmap %>
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
<%= yield %>
|
17
|
+
</body>
|
18
|
+
</html>
|
data/config/importmap.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Engine's own importmap configuration
|
2
|
+
pin "@hotwired/turbo-rails", to: "turbo.min.js"
|
3
|
+
pin "aven/application"
|
4
|
+
pin "@hotwired/stimulus", to: "stimulus.min.js"
|
5
|
+
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
|
6
|
+
|
7
|
+
pin_all_from(
|
8
|
+
Aven::Engine.root.join("app/javascript/aven/controllers"),
|
9
|
+
under: "aven/controllers",
|
10
|
+
)
|
11
|
+
|
12
|
+
pin_all_from(
|
13
|
+
Aven::Engine.root.join("app/components/aven"),
|
14
|
+
under: "aven/components",
|
15
|
+
to: "aven"
|
16
|
+
)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Devise.setup do |config|
|
4
|
+
# The secret key used by Devise will be taken from Rails credentials
|
5
|
+
# config.secret_key = Rails.application.credentials.secret_key_base
|
6
|
+
|
7
|
+
# ==> Mailer Configuration
|
8
|
+
config.mailer_sender = "noreply@nvoi.io"
|
9
|
+
|
10
|
+
# ==> ORM configuration
|
11
|
+
require "devise/orm/active_record"
|
12
|
+
|
13
|
+
# ==> Configuration for any authentication mechanism
|
14
|
+
# Configure which keys are used when authenticating a user
|
15
|
+
config.authentication_keys = [:email]
|
16
|
+
|
17
|
+
# ==> OAuth configuration
|
18
|
+
# GitHub OAuth will be configured with credentials from the host app
|
19
|
+
# The engine will receive credentials via configuration
|
20
|
+
|
21
|
+
# Configure sign out to use GET request (required for some OAuth providers)
|
22
|
+
config.sign_out_via = :get
|
23
|
+
|
24
|
+
# ==> Scopes configuration
|
25
|
+
config.scoped_views = true
|
26
|
+
|
27
|
+
# ==> Navigation configuration
|
28
|
+
config.navigational_formats = ['*/*', :html, :turbo_stream]
|
29
|
+
|
30
|
+
# The default HTTP method used to sign out a resource. Default is :delete.
|
31
|
+
config.sign_out_via = %i[delete get]
|
32
|
+
|
33
|
+
# ==> Mountable engine configuration
|
34
|
+
# Set parent controller for the engine
|
35
|
+
config.parent_controller = 'Aven::ApplicationController'
|
36
|
+
|
37
|
+
# ==> OmniAuth
|
38
|
+
# OmniAuth providers are configured dynamically via Aven.configuration
|
39
|
+
# in the engine initializer (lib/aven/engine.rb)
|
40
|
+
|
41
|
+
# Configure OmniAuth to work with the engine's mounted path
|
42
|
+
# config.omniauth_path_prefix = '/aven/users/auth'
|
43
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Aven::Engine.routes.draw do
|
2
|
+
devise_for(
|
3
|
+
:users, class_name: "Aven::User", module: :devise, format: false,
|
4
|
+
controllers: { omniauth_callbacks: "aven/auth" }
|
5
|
+
)
|
6
|
+
|
7
|
+
# Additional auth routes
|
8
|
+
get("/auth/:provider/authenticate", to: "auth#authenticate", as: :authenticate)
|
9
|
+
get("/auth/logout", to: "auth#logout", as: :logout)
|
10
|
+
|
11
|
+
namespace(:admin) do
|
12
|
+
root(to: "dashboard#index")
|
13
|
+
end
|
14
|
+
|
15
|
+
root(to: "static#index")
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateAvenUsers < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_users do |t|
|
4
|
+
t.string(:email, default: "", null: false)
|
5
|
+
t.string(:encrypted_password, default: "", null: false)
|
6
|
+
t.string(:reset_password_token)
|
7
|
+
t.datetime(:reset_password_sent_at)
|
8
|
+
t.datetime(:remember_created_at)
|
9
|
+
t.string(:auth_tenant)
|
10
|
+
t.string(:remote_id)
|
11
|
+
t.string(:access_token)
|
12
|
+
t.boolean(:admin, default: false, null: false)
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index(:aven_users, [:email, :auth_tenant], unique: true)
|
17
|
+
add_index(:aven_users, :reset_password_token, unique: true)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateAvenWorkspaces < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_workspaces do |t|
|
4
|
+
t.string :label
|
5
|
+
t.string :slug
|
6
|
+
t.text :description
|
7
|
+
t.string :domain
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :aven_workspaces, :slug, unique: true
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAvenWorkspaceUsers < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_workspace_users do |t|
|
4
|
+
t.references :user, null: false, foreign_key: { to_table: :aven_users }
|
5
|
+
t.references :workspace, null: false, foreign_key: { to_table: :aven_workspaces }
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :aven_workspace_users, [:user_id, :workspace_id], unique: true, name: "idx_aven_workspace_users_on_user_workspace"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateAvenWorkspaceRoles < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_workspace_roles do |t|
|
4
|
+
t.references :workspace, foreign_key: { to_table: :aven_workspaces }
|
5
|
+
t.string :label, null: false
|
6
|
+
t.string :description
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :aven_workspace_roles, [:workspace_id, :label], unique: true, name: "idx_aven_workspace_roles_on_ws_label"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAvenWorkspaceUserRoles < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_workspace_user_roles do |t|
|
4
|
+
t.references :workspace_role, foreign_key: { to_table: :aven_workspace_roles }
|
5
|
+
t.references :workspace_user, foreign_key: { to_table: :aven_workspace_users }
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :aven_workspace_user_roles, [:workspace_role_id, :workspace_user_id], unique: true, name: "idx_aven_ws_user_roles_on_role_user"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreateAvenLogs < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_logs do |t|
|
4
|
+
t.string :level, null: false, default: "info"
|
5
|
+
t.string :loggable_type, null: false
|
6
|
+
t.bigint :loggable_id, null: false
|
7
|
+
t.text :message, null: false
|
8
|
+
t.jsonb :metadata
|
9
|
+
t.string :state
|
10
|
+
t.string :state_machine
|
11
|
+
t.string :run_id
|
12
|
+
t.references :workspace, null: false, foreign_key: { to_table: :aven_workspaces }
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :aven_logs, :created_at
|
17
|
+
add_index :aven_logs, :level
|
18
|
+
add_index :aven_logs, [:loggable_type, :loggable_id], name: "index_aven_logs_on_loggable"
|
19
|
+
add_index :aven_logs, [:loggable_type, :loggable_id, :run_id, :state, :created_at], name: "idx_aven_logs_on_loggable_run_state_created_at"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAvenAppRecordSchemas < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_app_record_schemas do |t|
|
4
|
+
t.jsonb :schema, null: false
|
5
|
+
t.references :workspace, null: false, foreign_key: { to_table: :aven_workspaces }
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :aven_app_record_schemas, :schema, using: :gin
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateAvenAppRecords < ActiveRecord::Migration[8.0]
|
2
|
+
def change
|
3
|
+
create_table :aven_app_records do |t|
|
4
|
+
t.jsonb :data, null: false
|
5
|
+
t.references :app_record_schema, null: false, foreign_key: { to_table: :aven_app_record_schemas }
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :aven_app_records, :data, using: :gin
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Aven
|
2
|
+
class Configuration
|
3
|
+
attr_reader :auth
|
4
|
+
attr_accessor :authenticated_root_path
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@auth = Auth.new
|
8
|
+
@authenticated_root_path = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
class Auth
|
12
|
+
attr_reader :providers
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@providers = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(provider, *args, **options)
|
19
|
+
@providers << { provider: provider, args: args, options: options }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_writer :configuration
|
26
|
+
|
27
|
+
def configuration
|
28
|
+
@configuration ||= Configuration.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def configure
|
32
|
+
yield(configuration)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/aven/engine.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "devise"
|
2
|
+
require "omniauth"
|
3
|
+
require "omniauth/rails_csrf_protection"
|
4
|
+
require "repost"
|
5
|
+
require "importmap-rails"
|
6
|
+
require "view_component-contrib"
|
7
|
+
require "dry-effects"
|
8
|
+
require "tailwind_merge"
|
9
|
+
require "json_skooma"
|
10
|
+
require "aeros"
|
11
|
+
|
12
|
+
module Aven
|
13
|
+
class << self
|
14
|
+
attr_accessor :importmap
|
15
|
+
end
|
16
|
+
|
17
|
+
class Engine < ::Rails::Engine
|
18
|
+
isolate_namespace Aven
|
19
|
+
|
20
|
+
Aeros::EngineHelpers.setup_assets(self, namespace: Aven)
|
21
|
+
Aeros::EngineHelpers.setup_importmap(self, namespace: Aven)
|
22
|
+
|
23
|
+
# Ensure migrations are available to the host app
|
24
|
+
initializer "aven.migrations" do
|
25
|
+
unless Rails.env.test? || Rails.application.class.module_parent_name == "Dummy"
|
26
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
27
|
+
Rails.application.config.paths["db/migrate"] << expanded_path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
initializer "aven.devise", after: :load_config_initializers do
|
33
|
+
# Configure OmniAuth providers from Aven configuration
|
34
|
+
providers = Aven.configuration.auth.providers
|
35
|
+
|
36
|
+
# Add OmniAuth middleware
|
37
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
38
|
+
providers.each do |provider_config|
|
39
|
+
provider provider_config[:provider], *provider_config[:args], **provider_config[:options]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/aven/version.rb
ADDED