Skip to content

Commit

Permalink
Add an interface for users to personally update their organizations.
Browse files Browse the repository at this point in the history
Signed-off-by: EdmondFrank <[email protected]>
  • Loading branch information
EdmondFrank committed Jan 10, 2024
1 parent aad3575 commit 5a8fe75
Show file tree
Hide file tree
Showing 11 changed files with 1,068 additions and 5 deletions.
21 changes: 21 additions & 0 deletions app/controllers/concerns/compass_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ def redirect_url(error: nil, default_url: nil, skip_cookies: false)
uri.to_s
end

def get_uuid(*args)
def check_value(v)
if !v.is_a?(String)
raise ValueError, "%s value is not a string instance" % v.to_s
elsif v.empty?
raise ValueError, "value cannot be None or empty"
else
return v
end
end

def uuid(*args)
s = args.map{ |arg| check_value(arg) }.join(':')
sha1 = Digest::SHA1.hexdigest(s)
return sha1
end

args_list = args.select { |arg| !arg.nil? && !arg.empty? }
return uuid(*args_list)
end

def auto_break_line(text, max_length: 30)
broken_lines = []
current_line = ''
Expand Down
23 changes: 23 additions & 0 deletions app/graphql/input/contributor_org_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Input
class ContributorOrgInput < Types::BaseInputObject
argument :org_name, String, description: "organization's name"
argument :first_date, GraphQL::Types::ISO8601DateTime, description: 'time of begin of service by the organization'
argument :last_date, GraphQL::Types::ISO8601DateTime, description: 'time of end of service by the organization'

def self.validate_no_overlap(inputs)
ranges = inputs.map do |i|
if i.last_date < i.first_date
raise GraphQL::ExecutionError.new I18n.t('contributor_orgs.range_invalid')
end
(i.first_date..i.last_date)
end

overlaps = ranges.combination(2).any? { |r1, r2| (r1.min..r1.max).overlaps?(r2.min..r2.max) }
if overlaps
raise GraphQL::ExecutionError.new I18n.t('contributor_orgs.range_overlap')
end
end
end
end
45 changes: 45 additions & 0 deletions app/graphql/mutations/modify_user_orgs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module Mutations
class ModifyUserOrgs < BaseMutation
include CompassUtils

field :status, String, null: false

argument :platform, String, required: true, description: 'platform of the organization'
argument :organizations, [Input::ContributorOrgInput], required: true, description: 'contributor organizations'

def resolve(platform: nil, organizations: [])
current_user = context[:current_user]

login_required!(current_user)

Input::ContributorOrgInput.validate_no_overlap(organizations)

login_bind = current_user.login_binds.find_by(provider: platform)
raise GraphQL::ExecutionError.new I18n.t('users.no_such_login_bind') if login_bind.blank?
contributor = login_bind.nickname
uuid = get_uuid(contributor, ContributorOrg::UserIndividual, nil, nil, platform)
record = OpenStruct.new(
{
id: uuid,
uuid: uuid,
org_change_date_list: organizations,
modify_by: current_user.id,
modify_type: ContributorOrg::UserIndividual,
platform_type: platform,
is_bot: false,
label: nil,
level: nil,
update_at_date: Time.current
}
)

ContributorOrg.import(record)

{ status: true, message: '' }
rescue => ex
{ status: false, message: ex.message }
end
end
end
9 changes: 9 additions & 0 deletions app/graphql/types/contributor_org_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
module Types
class ContributorOrgType < Types::BaseObject
field :org_name, String, description: "organization's name"
field :first_date, GraphQL::Types::ISO8601DateTime, description: 'time of begin of service by the organization'
field :last_date, GraphQL::Types::ISO8601DateTime, description: 'time of end of service by the organization'
field :platform_type, String, description: 'platform type of the organization'
end
end
1 change: 1 addition & 0 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class MutationType < Types::BaseObject
field :sign_out, Boolean, description: 'Sign out'
field :destroy_user, Boolean, description: 'Destroy user'
field :modify_user, mutation: Mutations::ModifyUser, description: 'Modify user'
field :modify_user_orgs, mutation: Mutations::ModifyUserOrgs, description: 'Modify user organizations'
field :user_unbind, mutation: Mutations::UserUnbind, description: 'User unbind'
field :send_email_verify, mutation: Mutations::SendEmailVerify, description: 'Send email verify'
field :bind_wechat_link, mutation: Mutations::BindWechatLink, description: 'Bind wechat link'
Expand Down
5 changes: 5 additions & 0 deletions app/graphql/types/user_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class UserType < Types::BaseObject
field :email_verified, Boolean, null: false
field :subscriptions, Types::Subscription::SubscriptionPageType, null: false, resolver: Queries::SubscriptionsQuery
field :language, String, null: false
field :contributing_orgs, [Types::ContributorOrgType]

def email_verified
object.email_verified?
Expand All @@ -16,5 +17,9 @@ def email_verified
def email
object.anonymous? ? '' : object.email
end

def contributing_orgs
object.contributing_orgs
end
end
end
11 changes: 11 additions & 0 deletions app/models/contributor_org.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class ContributorOrg < BaseIndex
URL = 'URL'
RepoAdmin = 'Repo Admin'
UserIndividual = 'User Individual'

def self.index_name
'contributor_org'
end
end
13 changes: 13 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ def my_member_permission_of(model)
}
end

def contributing_orgs
ContributorOrg
.where(modify_by: self.id)
.must(match_phrase: { modify_type: ContributorOrg::UserIndividual })
.execute
.raw_response
.dig('hits', 'hits')
&.flat_map do |hit|
hit['_source']['org_change_date_list']
.map { |org| org.merge('platform_type' => hit['_source']['platform_type'] )}
end || []
end

def generate_email_verification_token
self.email_verification_token = loop do
random_token = SecureRandom.urlsafe_base64(nil, false)
Expand Down
Loading

0 comments on commit 5a8fe75

Please sign in to comment.