Skip to content

Commit

Permalink
Merge pull request #5 from paviliondev/add_aws_gem_management
Browse files Browse the repository at this point in the history
Add aws gem management
  • Loading branch information
angusmcleod authored Oct 21, 2024
2 parents cd7c29e + aab4ada commit be5cb36
Show file tree
Hide file tree
Showing 20 changed files with 566 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
inherit_gem:
rubocop-discourse: default.yml

Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
Enabled: false
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ GEM

PLATFORMS
arm64-darwin-22
arm64-darwin-23
x86_64-linux

DEPENDENCIES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,27 @@ def index
raise Discourse::InvalidParameters.new('user subscriptions require a valid request origin')
end

user_subs = SubscriptionServer::UserSubscriptions.new(current_user, domain)
user_subs.load(resources)
user_subscriptions = SubscriptionServer::UserSubscriptions.load(
current_user,
domain,
resources
)

render json: success_json.merge(subscriptions: serialize_data(user_subs.subscriptions, SubscriptionServer::SubscriptionSerializer))
user_resources = SubscriptionServer::UserResource.list(
current_user.id,
user_subscriptions
)

render json: success_json.merge(
subscriptions: serialize_data(
user_subscriptions,
SubscriptionServer::UserSubscriptionSerializer
),
resources: serialize_data(
user_resources,
SubscriptionServer::UserResourceSerializer
)
)
end

protected
Expand Down
15 changes: 15 additions & 0 deletions app/jobs/scheduled/subscription_server/expire_stale_keys.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module ::Jobs
class SubscriptionServerExpireStaleKeys < ::Jobs::Scheduled
every 1.week

def execute(args)
SubscriptionServer::UserResource.all.each do |user_resource|
if user_resource.ready? && user_resource.iam_key_updated_at > 3.weeks.ago
user_resource.expire_iam_keys!
end
end
end
end
end
101 changes: 101 additions & 0 deletions app/models/subscription_server/user_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# frozen_string_literal: true

module SubscriptionServer
class UserResource < ActiveRecord::Base

belongs_to :user

def iam_ready?
iam_user_name.present? && iam_access_key_id.present? && iam_secret_access_key.present?
end

def create_iam_user(iam)
key = aws.create_user(
user_name: self.user.username,
group_name: iam[:group]
)
if key
result = self.update(
iam_user_name: key[:user_name],
iam_access_key_id: key[:access_key_id],
iam_secret_access_key: key[:secret_access_key],
iam_key_updated_at: Time.now
)
end
end

def rotate_iam_key
return unless self.iam_user_name

key = aws.rotate_key(user_name: self.iam_user_name)
if key
self.update(
iam_access_key_id: key[:access_key_id],
iam_secret_access_key: key[:secret_access_key],
iam_key_updated_at: Time.now
)
end
end

def expire_iam_keys!
return unless self.iam_user_name

aws.expire_keys(user_name: self.iam_user_name)
end

def aws
@aws ||= SubscriptionServer::AWS.new
end

def self.list(user_id, subscriptions)
result = []

subscriptions.each do |subscription|
resource_name = subscription.resource
resource = SubscriptionServer::Subscription.subscription_map[resource_name]
next unless resource.present?

user_resource = self.find_or_create_by(
user_id: user_id,
resource_name: resource_name
)

if resource[:iam]
if !user_resource.iam_user_name
user_resource.create_iam_user(resource[:iam])
elsif !user_resource.iam_access_key_id
user_resource.rotate_iam_key
end
if user_resource.iam_key_updated_at > 1.week.ago
user_resource.rotate_iam_key
end
next unless user_resource.iam_ready?
end

result << user_resource.reload
end

result
end
end
end

# == Schema Information
#
# Table name: subscription_server_user_resources
#
# id :bigint not null, primary key
# user_id :bigint not null
# resource_name :string not null
# iam_user_name :string
# iam_access_key_id :string
# iam_secret_access_key :string
# iam_key_updated_at :string
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# idx_subscription_server_user_resources (user_id,resource_name) UNIQUE
# index_subscription_server_user_resources_on_user_id (user_id)
#
19 changes: 19 additions & 0 deletions app/serializers/subscription_server/user_resource_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class SubscriptionServer::UserResourceSerializer < ApplicationSerializer
attributes :resource,
:access_key_id,
:secret_access_key

def resource
object.resource_name
end

def access_key_id
object.iam_access_key_id
end

def secret_access_key
object.iam_secret_access_key
end
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class SubscriptionServer::SubscriptionSerializer < ApplicationSerializer
class SubscriptionServer::UserSubscriptionSerializer < ApplicationSerializer
attributes :resource,
:product_id,
:product_name,
Expand Down
5 changes: 4 additions & 1 deletion config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ en:
site_settings:
subscription_server_enabled: Enable subscription server
subscription_server_supplier_name: Supplier name, e.g. "Pavilion"
subscription_server_subscriptions: "List of supported subscriptions. resource:product_slug:provider:product_id:domain_limit e.g. discourse-custom-wizard:business:stripe:prod_Jyy6B9gyTJUURi:1"
subscription_server_subscriptions: "List of supported subscriptions. resource:product:provider:product_id:domain_limit:iam_group e.g. discourse-custom-wizard:business:stripe:prod_Jyy6B9gyTJUURi:1:custom_wizard"
subscription_server_iam_access_key: IAM Administrator Access Key
subscription_server_iam_secret_access_key: IAM Administrator Secret Access Key
subscription_server_iam_region: IAM region

user_api_key:
scopes:
Expand Down
5 changes: 4 additions & 1 deletion config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ plugins:
subscription_server_supplier_name: ''
subscription_server_subscriptions:
type: list
default: ''
default: ''
subscription_server_iam_access_key: ''
subscription_server_iam_secret_access_key: ''
subscription_server_iam_region: 'us-east-1'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true
class CreateSubscriptionServerUserResources < ActiveRecord::Migration[7.1]
def change
create_table :subscription_server_user_resources do |t|
t.references :user, null: false
t.string :resource_name, null: false
t.string :iam_user_name
t.string :iam_access_key_id
t.string :iam_secret_access_key
t.string :iam_key_updated_at

t.timestamps
end

add_index :subscription_server_user_resources,
%i[user_id resource_name],
unique: true,
name: :idx_subscription_server_user_resources
end
end
Loading

0 comments on commit be5cb36

Please sign in to comment.