forgeplus/app/models/concerns/project_operable.rb

264 lines
12 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module ProjectOperable
extend ActiveSupport::Concern
included do
has_many :members, dependent: :destroy
has_many :except_owner_members, -> { joins(:roles).where.not(roles: { name: 'Manager' }) }, class_name: 'Member'
has_many :managers, -> { joins(:roles).where(roles: { name: 'Manager' }) }, class_name: 'Member'
has_many :developers, -> { joins(:roles).where(roles: { name: 'Developer' }) }, class_name: 'Member'
has_many :reporters, -> { joins(:roles).where(roles: { name: 'Reporter' }) }, class_name: 'Member'
has_many :writable_members, -> { joins(:roles).where.not(roles: {name: 'Reporter'}) }, class_name: 'Member'
has_many :team_projects, dependent: :destroy
has_many :teams, through: :team_projects, source: :team
end
def set_owner_permission(creator)
return unless owner.is_a?(Organization)
owner.build_permit_team_projects!(id)
# 避免自己创建的项目,却无法拥有访问权,因为该用户所在团队暂未获得项目访问权
return if creator.nil? || owner.is_owner?(creator.id)
add_member!(creator.id, "Manager") if creator.is_a?(User)
end
def add_member!(user_id, role_name='Developer')
# if self.owner.is_a?(Organization)
# case role_name
# when 'Manager'
# # 构建相应的团队
# team = self.owner.teams.admin.take
# if team.nil?
# team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
#
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 新增对应的团队成员
# team_user = TeamUser.build(self.user_id, user_id, team.id)
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
#
# # 确保组织成员中有该用户
# OrganizationUser.build(self.user_id, user_id)
# when 'Developer'
# # 构建相应的团队
# team = self.owner.teams.write.take
# if team.nil?
# team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
#
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 新增对应的团队成员
# team_user = TeamUser.build(self.user_id, user_id, team.id)
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
#
# # 确保组织成员中有该用户
# OrganizationUser.build(self.user_id, user_id)
# when 'Reporter'
# # 构建相应的团队
# team = self.owner.teams.read.take
# if team.nil?
# team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
#
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 新增对应的团队成员
# team_user = TeamUser.build(self.user_id, user_id, team.id)
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
#
# # 确保组织成员中有该用户
# OrganizationUser.build(self.user_id, user_id)
# end
# end
# member = members.create!(user_id: user_id, team_user_id: team_user&.id)
member = members.create!(user_id: user_id)
set_developer_role(member, role_name)
end
def remove_member!(user_id)
member = members.find_by(user_id: user_id)
member.destroy! if member && self.user_id != user_id
team_user = TeamUser.find_by_id(member&.team_user_id)
team_user.destroy! if team_user
end
# 安装bot后的权限
def is_install_bot?(user)
user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?
end
def member?(user_id)
if owner.is_a?(User)
members.exists?(user_id: user_id) || is_install_bot?(User.find_by(id: user_id))
elsif owner.is_a?(Organization)
members.exists?(user_id: user_id) || team_projects.joins(team: :team_users).where(team_users: {user_id: user_id}).present?
else
false
end
end
# 除了项目创建者本身
def member(user_id)
members.where.not("members.user_id = ? ", owner.id).find_by(user_id: user_id)
end
def change_member_role!(user_id, role)
member = self.member(user_id)
# 所有者为组织,并且该用户属于组织成员
# if self.owner.is_a?(Organization) && member.team_user.present?
# case role&.name
# when 'Manager'
# # 构建相应的团队
# team = self.owner.teams.admin.take
# if team.nil?
# team = Team.build(self.user_id, 'admin', '管理员', '', 'admin', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
#
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 更改对应的团队成员
# team_user = member.team_user
# $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
# team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
#
# # 确保组织成员中有该用户
# OrganizationUser.build(self.user_id, user_id)
# when 'Developer'
# # 构建相应的团队
# team = self.owner.teams.write.take
# if team.nil?
# team = Team.build(self.user_id, 'developer', '开发者', '', 'write', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 更改对应的团队成员
# team_user = member.team_user
# $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
# team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
#
# OrganizationUser.build(self.user_id, user_id)
# when 'Reporter'
# # 构建相应的团队
# team = self.owner.teams.read.take
# if team.nil?
# team = Team.build(self.user_id, 'reporter', '报告者', '', 'read', false, false)
# gteam = $gitea_client.post_orgs_teams_by_org(self.owner.login, {body: team.to_gitea_hash.to_json}) rescue nil
# team.update_attributes!({gtid: gteam["id"]}) unless gteam.nil?
# end
#
# # 设置项目在团队中的访问权限
# team_project = TeamProject.build(self.user_id, team.id, self.id)
# tp_result = $gitea_client.put_teams_repos_by_id_org_repo(team.gtid, self.owner.login, self.identifier) rescue nil
#
# # 更改对应的团队成员
# team_user = member.team_user
# $gitea_client.delete_teams_members_by_id_username(team_user.team.gtid, team_user.user&.login) rescue nil # 移除旧的
# $gitea_client.put_teams_members_by_id_username(team&.gtid, team_user.user&.login) rescue nil # 新增新的
# team_user.update_attributes!({team_id: team.id}) unless team.team_users.exists?(user_id: member.user_id)
#
# # 确保组织成员中有该用户
# OrganizationUser.build(self.user_id, user_id)
# end
# end
member.member_roles.last.update_attributes!(role: role)
end
def owner?(user)
if owner.is_a?(User)
self.owner == user
elsif owner.is_a?(Organization)
owner.is_owner?(user.id)
else
false
end
end
# 项目管理员(包含项目拥有者),权限:仓库设置、仓库可读可写
# 增加bot用户权限已安装bot当前bot用户即拥有权限权限粒度待完善
def manager?(user)
if owner.is_a?(User)
managers.exists?(user_id: user.id) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?)
elsif owner.is_a?(Organization)
managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || (owner.is_admin?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?)
else
false
end
end
# 项目开发者,可读可写权限
# 增加bot用户权限已安装当前bot用户对应的bot即拥有权限权限粒度待完善
def develper?(user)
if owner.is_a?(User)
developers.exists?(user_id: user.id) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?)
elsif owner.is_a?(Organization)
developers.exists?(user_id: user.id) || (owner.is_write?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?)
else
false
end
end
# 报告者,只有可读权限
def reporter?(user)
if owner.is_a?(User)
reporters.exists?(user_id: user.id)
elsif owner.is_a?(Organization)
reporters.exists?(user_id: user.id) || owner.is_only_read?(user.id)
else
false
end
end
def operator?(user)
user.admin? || (member?(user.id) && !reporter?(user))
end
def set_developer_role(member, role_name)
role = Role.find_by(name: role_name)
member.member_roles.create!(role: role)
end
def has_menu_permission(unit_type)
self.project_units.where(unit_type: unit_type).exists?
end
def all_collaborators
member_sql = User.joins(members: :roles).where(members: {project_id: self.id}, roles: {name: %w(Manager Developer Reporter)}).to_sql
team_user_sql = User.joins(teams: :team_projects).where(team_projects: {project_id: self.id}).to_sql
return User.from("( #{ member_sql } UNION #{ team_user_sql } ) AS users").distinct
end
def all_developers
member_sql = User.joins(members: :roles).where(members: {project_id: self.id}, roles: {name: %w(Manager Developer)}).to_sql
team_user_sql = User.joins(teams: :team_projects).where(teams: {authorize: %w(owner admin write)}, team_projects: {project_id: self.id}).to_sql
return User.from("( #{ member_sql } UNION #{ team_user_sql } ) AS users").distinct
end
def all_managers
member_sql = User.joins(members: :roles).where(members: {project_id: self.id}, roles: {name: %w(Manager)}).to_sql
team_user_sql = User.joins(teams: :team_projects).where(teams: {authorize: %w(owner admin)},team_projects: {project_id: self.id}).to_sql
return User.from("( #{ member_sql} UNION #{ team_user_sql } ) AS users").distinct
end
end