diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7bf88abc5..ee81765a5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -680,7 +680,7 @@ class ApplicationController < ActionController::Base relation.page(page).per(limit) end - def kaminary_array_paginate(relation) + def kaminari_array_paginate(relation) limit = params[:limit] || params[:per_page] limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i page = params[:page].to_i.zero? ? 1 : params[:page].to_i diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index 346f996e7..e475d19b9 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -1,22 +1,25 @@ class Organizations::BaseController < ApplicationController include ApplicationHelper - def load_organization - @organization = Organization.find_by(login: params[:id]) || Organization.find_by(id: params[:id]) + protected - @organization = nil if limited_condition || privacy_condition - - render_not_found if @organization.nil? - - @organization + def organization_owner + @organization.team_users.joins(:team).where(teams: {authorize: 'owner'}).take.user end - private - def limited_condition + def org_limited_condition @organization.organization_extension.limited? && !current_user.logged? end - def privacy_condition + def org_privacy_condition @organization.organization_extension.privacy? && @organization.organization_users.where(user_id: current_user.id).blank? end + + def team_not_found_condition + @team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user) + end + + def user_mark + params[:username] || params[:id] + end end \ No newline at end of file diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb new file mode 100644 index 000000000..562c754bf --- /dev/null +++ b/app/controllers/organizations/organization_users_controller.rb @@ -0,0 +1,55 @@ +class Organizations::OrganizationUsersController < Organizations::BaseController + before_action :load_organization + before_action :load_operate_user, only: [:destroy] + before_action :load_organization_user, only: [:destroy] + + def index + @organization_users = @organization.organization_users.includes(:user) + + @organization_users = kaminari_paginate(@organization_users) + end + + def destroy + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + ActiveRecord::Base.transaction do + @organization_user.destroy! + TeamUser.where(organization_id: @organization.id, user_id: @operate_user.id).map{|u| u.destroy!} + Gitea::Organization::OrganizationUser::DeleteService.call(current_user.gitea_token, @organization.login, @operate_user.login) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def quit + @organization_user = @organization.organization_users.find_by(user_id: current_user.id) + tip_exception("您不在该组织中") if @organization_user.nil? + ActiveRecord::Base.transaction do + @organization_user.destroy! + TeamUser.where(organization_id: @organization.id, user_id: current_user.id).map{|u| u.destroy!} + Gitea::Organization::OrganizationUser::DeleteService.call(organization_owner.gitea_token, @organization.login, current_user.login) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def load_organization + @organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id]) + tip_exception("组织不存在") if @organization.nil? + tip_exception("没有查看组织的权限") if org_limited_condition || org_privacy_condition + end + + def load_operate_user + @operate_user = User.find_by(login: user_mark) if user_mark.present? + tip_exception("平台用户不存在") if @operate_user.nil? + end + + def load_organization_user + @organization_user = OrganizationUser.find_by(organization_id: @organization.id, user_id: @operate_user.id) + tip_exception("组织成员不存在") if @organization_user.nil? + end +end \ No newline at end of file diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index ccdb68ecc..93ec7c4e1 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -5,17 +5,17 @@ class Organizations::OrganizationsController < Organizations::BaseController def index if current_user.logged? - @organizations = Organization.with_visibility(%w(common limited)) + - Organization.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}) - kaminary_array_paginate(@organizations) + logged_organizations_sql = Organization.with_visibility(%w(common limited)).to_sql + privacy_organizations_sql = Organization.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).to_sql + @organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users") else @organizations = Organization.with_visibility("common") - kaminari_paginate(@organizations) end + @organizations = @organizations.includes(:organization_extension).order(id: :asc) + @organizations = kaminari_paginate(@organizations) end def show - end def create @@ -29,11 +29,12 @@ class Organizations::OrganizationsController < Organizations::BaseController end def update + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) ActiveRecord::Base.transaction do login = @organization.login @organization.update!(login: organization_params[:name]) if organization_params[:name].present? @organization.organization_extension.update_attributes!(organization_params.except(:name)) - Gitea::Organization::UpdateService.call(current_user.gitea_token, login, @organization) + Gitea::Organization::UpdateService.call(current_user.gitea_token, login, @organization.reload) Util.write_file(@image, avatar_path(@organization)) if params[:image].present? end rescue Exception => e @@ -42,8 +43,8 @@ class Organizations::OrganizationsController < Organizations::BaseController end def destroy - render_unauthorized unless current_user.check_password?(password) - render_forbidden("您没有权限进行该操作") unless @organization.check_owner?(current_user) + tip_exception("密码不正确") unless current_user.check_password?(password) + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) ActiveRecord::Base.transaction do Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login) @organization.destroy! @@ -76,4 +77,10 @@ class Organizations::OrganizationsController < Organizations::BaseController params.fetch(:password, "") end + def load_organization + @organization = Organization.find_by(login: params[:id]) || Organization.find_by(id: params[:id]) + tip_exception("组织不存在") if @organization.nil? + tip_exception("没有查看组织的权限") if org_limited_condition || org_privacy_condition + end + end \ No newline at end of file diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb new file mode 100644 index 000000000..6097331f6 --- /dev/null +++ b/app/controllers/organizations/team_users_controller.rb @@ -0,0 +1,74 @@ +class Organizations::TeamUsersController < Organizations::BaseController + before_action :load_organization, :load_team + before_action :load_operate_user, only: [:create, :destroy] + before_action :load_team_user, only: [:destroy] + + def index + @team_users = @team.team_users + + @team_users = kaminari_paginate(@team_users) + end + + def create + render_forbidden("您没有权限进行该操作") unless @organization.is_owner?(current_user) + ActiveRecord::Base.transaction do + @team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id) + @organization_user = OrganizationUser.build(@organization.id, @operate_user.id) + Gitea::Organization::TeamUser::CreateService.call(current_user.gitea_token, @team.gtid, @operate_user.login) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @team.num_users == 1 + ActiveRecord::Base.transaction do + @team_user.destroy! + Gitea::Organization::TeamUser::DeleteService.call(current_user.gitea_token, @team.gtid, @operate_user.login) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def quit + @team_user = @team.team_users.find_by(user_id: current_user.id) + tip_exception("您不在该组织团队中") if @team_user.nil? + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @team.num_users == 1 + ActiveRecord::Base.transaction do + @team_user.destroy! + Gitea::Organization::TeamUser::DeleteService.call(organization_owner.gitea_token, @team.gtid, current_user.login) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def load_organization + @organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id]) + tip_exception("组织不存在") if @organization.nil? + tip_exception("没有查看组织的权限") if org_limited_condition || org_privacy_condition + end + + def load_team + @team = Team.find_by_id(params[:team_id]) + tip_exception("组织团队不存在") if @team.nil? + tip_exception("没有查看组织团队的权限") if team_not_found_condition + end + + def load_operate_user + @operate_user = User.find_by(login: user_mark) if user_mark.present? + tip_exception("平台用户不存在") if @operate_user.nil? + end + + def load_team_user + @team_user = TeamUser.find_by(team_id: @team.id, user_id: @operate_user.id) + tip_exception("组织团队成员不存在") if @team_user.nil? + end + +end \ No newline at end of file diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb new file mode 100644 index 000000000..56b11a9fc --- /dev/null +++ b/app/controllers/organizations/teams_controller.rb @@ -0,0 +1,62 @@ +class Organizations::TeamsController < Organizations::BaseController + before_action :load_organization + before_action :load_team, only: [:show, :update, :destroy] + + def index + if @organization.is_owner?(current_user) + @teams = @organization.teams + else + @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) + end + + @teams = kaminari_paginate(@teams) + end + + def show + end + + def create + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + @team = Organizations::Teams::CreateService.call(current_user, @organization, team_params) + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def update + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + @team = Organizations::Teams::UpdateService.call(current_user, @team, team_params) + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + ActiveRecord::Base.transaction do + Gitea::Organization::Team::DeleteService.call(current_user.gitea_token, @team.gtid) + @team.destroy! + end + render_ok + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def team_params + params.permit(:name, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types => []) + end + + def load_organization + @organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id]) + tip_exception("组织不存在") if @organization.nil? + tip_exception("没有查看组织的权限") if org_limited_condition || org_privacy_condition + end + + def load_team + @team = Team.find_by_id(params[:id]) + tip_exception("组织团队不存在") if @team.nil? + tip_exception("没有查看组织团队的权限") if team_not_found_condition + end +end \ No newline at end of file diff --git a/app/controllers/users/organizations_controller.rb b/app/controllers/users/organizations_controller.rb new file mode 100644 index 000000000..b0bfbd037 --- /dev/null +++ b/app/controllers/users/organizations_controller.rb @@ -0,0 +1,14 @@ +class Users::OrganizationsController < Users::BaseController + + def index + if current_user.logged? + logged_organizations_sql = observed_user.organizations.with_visibility(%w(common limited)).to_sql + privacy_organizations_sql = observed_user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).to_sql + @organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users") + else + @organizations = observed_user.organizations.with_visibility("common") + end + + @organizations = @organizations.includes(:organization_extension).order(id: :asc) + end +end \ No newline at end of file diff --git a/app/models/organization.rb b/app/models/organization.rb index c3ebda1d7..5a8594925 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -78,11 +78,8 @@ class Organization < ApplicationRecord self.create!(login: name) end - def owner_team - teams.where(authorize: 4).take + def is_owner?(user) + team_users.joins(:team).where(user_id: user.id, teams: {authorize: %w(owner)}).present? end - def check_owner?(user) - owner_team.team_users.where(user_id: user.id).present? - end end diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index cfd5cc9f5..dd8790235 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -18,8 +18,17 @@ class OrganizationUser < ApplicationRecord belongs_to :organization + belongs_to :user - def self.build(organization_id, user_id, is_creator) + validates :user_id, uniqueness: {scope: :organization_id} + + def self.build(organization_id, user_id, is_creator = false) + org_user = self.find_by(organization_id: organization_id, user_id: user_id) + return org_user unless org_user.nil? self.create!(organization_id: organization_id, user_id: user_id, is_creator: is_creator) end + + def teams + organization.teams.joins(:team_users).where(team_users: {user_id: user_id}) + end end diff --git a/app/models/team.rb b/app/models/team.rb index a37cade73..125517bab 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -27,6 +27,8 @@ class Team < ApplicationRecord has_many :team_units, dependent: :destroy has_many :team_users, dependent: :destroy + validates :name, uniqueness: {scope: :organization_id} + enum authorize: {common: 0, read: 1, write: 2, admin: 3, owner: 4} def self.build(organization_id, name, description, authorize, includes_all_project, can_create_org_project) @@ -38,7 +40,4 @@ class Team < ApplicationRecord can_create_org_project: can_create_org_project) end - def self.build_owner(organization_id) - self.build(organization_id, "Owner", "", 4, true, true) - end end diff --git a/app/models/team_project.rb b/app/models/team_project.rb index 7ae475d8c..75c62b488 100644 --- a/app/models/team_project.rb +++ b/app/models/team_project.rb @@ -22,6 +22,8 @@ class TeamProject < ApplicationRecord belongs_to :project belongs_to :team, counter_cache: :num_projects + validates :project_id, uniqueness: {scope: :organization_id} + def self.build(organization_id, team_id, project_id) self.create!(organization_id: organization_id, team_id: team_id, project_id: project_id) end diff --git a/app/models/team_unit.rb b/app/models/team_unit.rb index f655f01fd..c757cc684 100644 --- a/app/models/team_unit.rb +++ b/app/models/team_unit.rb @@ -20,7 +20,7 @@ class TeamUnit < ApplicationRecord belongs_to :organization belongs_to :team - enum unit_type: {code: 1, issue: 2, pull_request: 3, releases: 4} + enum unit_type: {code: 1, issues: 2, pulls: 3, releases: 4} validates :unit_type, uniqueness: { scope: [:organization_id, :team_id]} @@ -28,9 +28,4 @@ class TeamUnit < ApplicationRecord self.create!(organization_id: organization_id, team_id: team_id, unit_type: unit_type) end - def self.build_owner(organization_id, team_id) - self.unit_types.keys.each do |u_type| - self.build(organization_id, team_id, u_type) - end - end end diff --git a/app/models/team_user.rb b/app/models/team_user.rb index 57cef55f3..9670013a7 100644 --- a/app/models/team_user.rb +++ b/app/models/team_user.rb @@ -22,6 +22,8 @@ class TeamUser < ApplicationRecord belongs_to :team, counter_cache: :num_users belongs_to :user + validates :user_id, uniqueness: {scope: [:organization_id, :team_id]} + def self.build(organization_id, user_id, team_id) self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id) end diff --git a/app/models/user.rb b/app/models/user.rb index a94a30fdf..4341f0c87 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -163,6 +163,9 @@ class User < ApplicationRecord has_many :project_trends, dependent: :destroy has_many :oauths , dependent: :destroy + has_many :organization_users, dependent: :destroy + has_many :organizations, through: :organization_users + # Groups and active users scope :active, lambda { where(status: STATUS_ACTIVE) } scope :like, lambda { |keywords| diff --git a/app/services/gitea/organization/create_service.rb b/app/services/gitea/organization/create_service.rb index 4b20b2264..4da1720cc 100644 --- a/app/services/gitea/organization/create_service.rb +++ b/app/services/gitea/organization/create_service.rb @@ -19,7 +19,8 @@ class Gitea::Organization::CreateService < Gitea::ClientService location: org.location, repo_admin_change_team_access: org.repo_admin_change_team_access, visibility: visibility(org.visibility), - website: org.website + website: org.website, + max_repo_creation: org.max_repo_creation } Hash.new.merge(token: token, data: create_params) end diff --git a/app/services/gitea/organization/organization_user/delete_service.rb b/app/services/gitea/organization/organization_user/delete_service.rb new file mode 100644 index 000000000..ef6d48947 --- /dev/null +++ b/app/services/gitea/organization/organization_user/delete_service.rb @@ -0,0 +1,23 @@ +class Gitea::Organization::OrganizationUser::DeleteService < Gitea::ClientService + attr_reader :token, :org_name, :username + + def initialize(token, org_name, username) + @token = token + @org_name = org_name + @username = username + end + + def call + response = delete(url, params) + render_status(response) + end + + private + def params + Hash.new.merge(token: token) + end + + def url + "/orgs/#{org_name}/members/#{username}" + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team/create_service.rb b/app/services/gitea/organization/team/create_service.rb new file mode 100644 index 000000000..3e9340af4 --- /dev/null +++ b/app/services/gitea/organization/team/create_service.rb @@ -0,0 +1,50 @@ +class Gitea::Organization::Team::CreateService < Gitea::ClientService + attr_reader :token, :org, :team + + def initialize(token, org, team) + @token = token + @org = org + @team = team + end + + def call + response = post(url, request_params) + render_status(response) + end + + private + def request_params + create_params = { + name: team.name, + description: team.description, + permission: permission(team.authorize), + includes_all_repositories: team.includes_all_project, + can_create_org_repo: team.can_create_org_project, + units: unit_arrays + } + Hash.new.merge(token: token, data: create_params) + end + + def permission(authorize) + case authorize + when "read" + "read" + when "write" + "write" + when "admin" + "admin" + when "owner" + "owner" + else + "none" + end + end + + def unit_arrays + team.team_units.pluck(:unit_type).collect{|t|"repo.#{t}"} + end + + def url + "/orgs/#{org.login}/teams".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team/delete_service.rb b/app/services/gitea/organization/team/delete_service.rb new file mode 100644 index 000000000..4f94352bf --- /dev/null +++ b/app/services/gitea/organization/team/delete_service.rb @@ -0,0 +1,22 @@ +class Gitea::Organization::Team::DeleteService < Gitea::ClientService + attr_reader :token, :gtid + + def initialize(token, gtid) + @token = token + @gtid = gtid + end + + def call + response = delete(url, params) + render_status(response) + end + + private + def params + Hash.new.merge(token: token) + end + + def url + "/teams/#{gtid}".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team/update_service.rb b/app/services/gitea/organization/team/update_service.rb new file mode 100644 index 000000000..68be59453 --- /dev/null +++ b/app/services/gitea/organization/team/update_service.rb @@ -0,0 +1,49 @@ +class Gitea::Organization::Team::UpdateService < Gitea::ClientService + attr_reader :token, :team + + def initialize(token, team) + @token = token + @team = team + end + + def call + response = patch(url, request_params) + render_status(response) + end + + private + def request_params + update_params = { + name: team.name, + description: team.description, + permission: permission(team.authorize), + includes_all_repositories: team.includes_all_project, + can_create_org_repo: team.can_create_org_project, + units: unit_arrays + } + Hash.new.merge(token: token, data: update_params) + end + + def permission(authorize) + case authorize + when "read" + "read" + when "write" + "write" + when "admin" + "admin" + when "owner" + "owner" + else + "none" + end + end + + def unit_arrays + team.team_units.pluck(:unit_type).collect{|t|"repo.#{t}"} + end + + def url + "/teams/#{team.gtid}".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team_user/create_service.rb b/app/services/gitea/organization/team_user/create_service.rb new file mode 100644 index 000000000..11aa4da23 --- /dev/null +++ b/app/services/gitea/organization/team_user/create_service.rb @@ -0,0 +1,23 @@ +class Gitea::Organization::TeamUser::CreateService < Gitea::ClientService + attr_reader :token, :gtid, :username + + def initialize(token, gtid, username) + @token = token + @gtid = gtid + @username = username + end + + def call + response = put(url, request_params) + render_status(response) + end + + private + def request_params + Hash.new.merge(token: token) + end + + def url + "/teams/#{gtid}/members/#{username}".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team_user/delete_service.rb b/app/services/gitea/organization/team_user/delete_service.rb new file mode 100644 index 000000000..199f86956 --- /dev/null +++ b/app/services/gitea/organization/team_user/delete_service.rb @@ -0,0 +1,23 @@ +class Gitea::Organization::TeamUser::DeleteService < Gitea::ClientService + attr_reader :token, :gtid, :username + + def initialize(token, gtid, username) + @token = token + @gtid = gtid + @username = username + end + + def call + response = delete(url, params) + render_status(response) + end + + private + def params + Hash.new.merge(token: token) + end + + def url + "/teams/#{gtid}/members/#{username}" + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/update_service.rb b/app/services/gitea/organization/update_service.rb index 7655d5f38..c04dcbc86 100644 --- a/app/services/gitea/organization/update_service.rb +++ b/app/services/gitea/organization/update_service.rb @@ -15,12 +15,13 @@ class Gitea::Organization::UpdateService < Gitea::ClientService private def request_params update_params = { - username: org.login, + name: org.login, description: org.description, location: org.location, repo_admin_change_team_access: org.repo_admin_change_team_access, visibility: visibility(org.visibility), - website: org.website + website: org.website, + max_repo_creation: org.max_repo_creation } Hash.new.merge(token: token, data: update_params) end diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index f09b9f833..da5fdd2d8 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -1,5 +1,6 @@ class Organizations::CreateService < ApplicationService attr_reader :user, :params + attr_accessor :organization, :gitea_organization, :owner_team def initialize(user, params) @user = user @@ -10,32 +11,27 @@ class Organizations::CreateService < ApplicationService Rails.logger.info("######Organization create_service begin######") Rails.logger.info("######params #{params}######") ActiveRecord::Base.transaction do - @organization = Organization.build(params[:name]) - org_extension = OrganizationExtension.build(@organization.id, description, website, - location, repo_admin_change_team_access, - visibility, max_repo_creation) - team = Team.build_owner(@organization.id) - TeamUnit.build_owner(@organization.id, team.id) - OrganizationUser.build(@organization.id, user.id, true) - TeamUser.build(@organization.id, user.id, team.id) - - Gitea::Organization::CreateService.call(user.gitea_token, @organization) + create_org_and_extension + create_owner_info + create_gitea_org + sync_owner_team_gtid Rails.logger.info("######Organization create_service end######") end @organization end + private def description - params[:description].present? ? params[:description] : nil + params[:description] end def website - params[:website].present? ? params[:website] : nil + params[:website] end def location - params[:location].present? ? params[:location] : nil + params[:location] end def repo_admin_change_team_access @@ -49,4 +45,28 @@ class Organizations::CreateService < ApplicationService def max_repo_creation params[:max_repo_creation].present? ? params[:max_repo_creation] : -1 end + + def create_org_and_extension + @organization = Organization.build(params[:name]) + org_extension = OrganizationExtension.build(organization.id, description, website, + location, repo_admin_change_team_access, + visibility, max_repo_creation) + end + + def create_owner_info + @owner_team = Team.build(organization.id, "Owner", "", 4, true, true) + TeamUnit.unit_types.keys.each do |u_type| + TeamUnit.build(organization.id, owner_team.id, u_type) + end + OrganizationUser.build(organization.id, user.id, true) + TeamUser.build(organization.id, user.id, owner_team.id) + end + + def create_gitea_org + @gitea_organization = Gitea::Organization::CreateService.call(user.gitea_token, organization) + end + + def sync_owner_team_gtid + owner_team.update!(gtid: gitea_organization["owner_team"]["id"]) + end end \ No newline at end of file diff --git a/app/services/organizations/teams/create_service.rb b/app/services/organizations/teams/create_service.rb new file mode 100644 index 000000000..9a26e3c65 --- /dev/null +++ b/app/services/organizations/teams/create_service.rb @@ -0,0 +1,74 @@ +class Organizations::Teams::CreateService < ApplicationService + attr_reader :user, :org, :params + attr_accessor :team, :gitea_team + + def initialize(user, org, params) + @user = user + @org = org + @params = params + end + + def call + Rails.logger.info("######Team create_service begin######") + Rails.logger.info("######params #{params}######") + ActiveRecord::Base.transaction do + create_team + create_units + create_gitea_team + sync_team_gtid + end + Rails.logger.info("######Team create_service end######") + + team + end + + private + def name + params[:name] + end + + def description + params[:description] + end + + def authorize + params[:authorize].present? ? params[:authorize] : "common" + end + + def includes_all_project + params[:includes_all_project].present? ? params[:includes_all_project] : false + end + + def can_create_org_project + params[:can_create_org_project].present? ? params[:can_create_org_project] : false + end + + def create_team + @team = Team.build(org.id, name, description, authorize, + includes_all_project, can_create_org_project) + end + + def units_params + %w(admin owner).include?(authorize) ? %w(code issues pulls releases) : params[:unit_types] + end + + def create_units + return if units_params.blank? + begin + units_params.each do |unit| + TeamUnit.build(org.id, team.id, unit) + end + rescue + raise ActiveRecord::Rollback, "TeamUnit create error" + end + end + + def create_gitea_team + @gitea_team = Gitea::Organization::Team::CreateService.call(user.gitea_token, org, team) + end + + def sync_team_gtid + team.update!(gtid: gitea_team["id"]) + end + +end \ No newline at end of file diff --git a/app/services/organizations/teams/update_service.rb b/app/services/organizations/teams/update_service.rb new file mode 100644 index 000000000..d7599d0cf --- /dev/null +++ b/app/services/organizations/teams/update_service.rb @@ -0,0 +1,58 @@ +class Organizations::Teams::UpdateService < ApplicationService + attr_reader :user, :team, :params + + def initialize(user, team, params) + @user = user + @team = team + @params = params + end + + def call + Rails.logger.info("######Team update_service begin######") + Rails.logger.info("######params #{params}######") + ActiveRecord::Base.transaction do + update_team(update_params) + update_units + team.reload + update_gitea_team + end + Rails.logger.info("######Team update_service end######") + + team + end + + private + def update_params + if team.authorize == "owner" + update_params = params.slice(:description) + else + update_params = params.slice(:name, :description, :authorize, :includes_all_project, :can_create_org_project) + end + update_params + end + + def units_params + %w(admin owner).include?(team.authorize) ? %w(code issues pulls releases) : params[:unit_types] + end + + def update_team(update_params) + team.update_attributes!(update_params) + end + + def update_units + return if units_params.blank? + begin + team.team_units.map{|u|u.destroy!} + Rails.logger.info units_params + units_params.each do |unit| + TeamUnit.build(team&.organization&.id, team.id, unit) + end + rescue + raise ActiveRecord::Rollback, "TeamUnit update error" + end + end + + def update_gitea_team + Gitea::Organization::Team::UpdateService.call(user.gitea_token, team) + end +end \ No newline at end of file diff --git a/app/views/organizations/organization_users/_detail.json.jbuilder b/app/views/organizations/organization_users/_detail.json.jbuilder new file mode 100644 index 000000000..20696efcd --- /dev/null +++ b/app/views/organizations/organization_users/_detail.json.jbuilder @@ -0,0 +1,6 @@ +json.id org_user.id +json.user do + json.partial! "/users/user", user: org_user.user +end + +json.team_names org_user.teams.pluck(:name) \ No newline at end of file diff --git a/app/views/organizations/organization_users/index.json.jbuilder b/app/views/organizations/organization_users/index.json.jbuilder new file mode 100644 index 000000000..361c3f242 --- /dev/null +++ b/app/views/organizations/organization_users/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @organization_users.total_count +json.organization_users @organization_users do |org_user| + json.partial! "detail", org_user: org_user, organization: @organization +end diff --git a/app/views/organizations/team_users/_detail.json.jbuilder b/app/views/organizations/team_users/_detail.json.jbuilder new file mode 100644 index 000000000..c6c93e779 --- /dev/null +++ b/app/views/organizations/team_users/_detail.json.jbuilder @@ -0,0 +1,4 @@ +json.id team_user.id +json.user do + json.partial! "/users/user", user: team_user.user +end \ No newline at end of file diff --git a/app/views/organizations/team_users/create.json.jbuilder b/app/views/organizations/team_users/create.json.jbuilder new file mode 100644 index 000000000..7f6a5280d --- /dev/null +++ b/app/views/organizations/team_users/create.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", team_user: @team_user, team: @team, organization: @organization \ No newline at end of file diff --git a/app/views/organizations/team_users/index.json.jbuilder b/app/views/organizations/team_users/index.json.jbuilder new file mode 100644 index 000000000..ee569aacf --- /dev/null +++ b/app/views/organizations/team_users/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @team_users.total_count +json.team_users @team_users do |team_user| + json.partial! "detail", team_user: team_user, team: @team, organization: @organization +end diff --git a/app/views/organizations/teams/_detail.json.jbuilder b/app/views/organizations/teams/_detail.json.jbuilder new file mode 100644 index 000000000..36011a98f --- /dev/null +++ b/app/views/organizations/teams/_detail.json.jbuilder @@ -0,0 +1,9 @@ +json.id team.id +json.name team.name +json.description team.description +json.authorize team.authorize +json.includes_all_project team.includes_all_project +json.can_create_org_project team.can_create_org_project +json.num_projects team.num_projects +json.num_users team.num_users +json.units team.team_units.pluck(:unit_type) diff --git a/app/views/organizations/teams/create.json.jbuilder b/app/views/organizations/teams/create.json.jbuilder new file mode 100644 index 000000000..25f229ce8 --- /dev/null +++ b/app/views/organizations/teams/create.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", team: @team, organization: @organization \ No newline at end of file diff --git a/app/views/organizations/teams/index.json.jbuilder b/app/views/organizations/teams/index.json.jbuilder new file mode 100644 index 000000000..ad3479ec4 --- /dev/null +++ b/app/views/organizations/teams/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @teams.total_count +json.teams @teams do |team| + json.partial! "detail", team: team, organization: @organization +end diff --git a/app/views/organizations/teams/show.json.jbuilder b/app/views/organizations/teams/show.json.jbuilder new file mode 100644 index 000000000..25f229ce8 --- /dev/null +++ b/app/views/organizations/teams/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", team: @team, organization: @organization \ No newline at end of file diff --git a/app/views/organizations/teams/update.json.jbuilder b/app/views/organizations/teams/update.json.jbuilder new file mode 100644 index 000000000..25f229ce8 --- /dev/null +++ b/app/views/organizations/teams/update.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", team: @team, organization: @organization \ No newline at end of file diff --git a/app/views/users/organizations/index.json.jbuilder b/app/views/users/organizations/index.json.jbuilder new file mode 100644 index 000000000..3a3100b43 --- /dev/null +++ b/app/views/users/organizations/index.json.jbuilder @@ -0,0 +1,3 @@ +json.organizations @organizations do |organization| + json.partial! "/organizations/organizations/detail", organization: organization +end diff --git a/config/routes.rb b/config/routes.rb index 851a58150..8442994d4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -104,14 +104,19 @@ Rails.application.routes.draw do delete 'commons/delete', to: 'commons#delete' scope module: :organizations do - resources :organizations do - - end - resources :teams do - resources :team_users do + resources :organizations, except: [:edit, :new] do + resources :organization_users, only: [:index, :destroy] do + collection do + delete :quit + end end - resources :team_projects do - + resources :teams, except: [:edit, :new] do + resources :team_users, only: [:index, :create, :destroy] do + collection do + delete :quit + end + end + resources :team_projects, only: [:index, :create, :destroy] do ;end end end end @@ -238,6 +243,7 @@ Rails.application.routes.draw do end scope module: :users do + resources :organizations, only: [:index] # resources :projects, only: [:index] # resources :subjects, only: [:index] resources :project_packages, only: [:index]