diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 2939e7fb..c8f3027d 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -76,7 +76,7 @@ class ProjectsController < ApplicationController default_branch: params[:default_branch] } if [true, false].include? private - new_project_params = project_params.merge(is_public: !private) + new_project_params = project_params.except(:private).merge(is_public: !private) Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params) @project.repository.update_column(:hidden, private) end diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 519a63bd..6683dde4 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -88,7 +88,7 @@ class RepositoriesController < ApplicationController end def edit - return render_forbidden if !@project.manager?(current_user) + return render_forbidden if !@project.manager?(current_user) && !current_user.admin? end def create_file diff --git a/app/forms/projects/migrate_form.rb b/app/forms/projects/migrate_form.rb index f17b75a5..51116b2b 100644 --- a/app/forms/projects/migrate_form.rb +++ b/app/forms/projects/migrate_form.rb @@ -2,7 +2,7 @@ class Projects::MigrateForm < BaseForm REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i - attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, :project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password + attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, :project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner validates :user_id, :name, :description,:repository_name, :project_category_id, :project_language_id, presence: true validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } @@ -12,6 +12,18 @@ class Projects::MigrateForm < BaseForm check_repository_name(user_id, repository_name) unless repository_name.blank? check_project_category(project_category_id) check_project_language(project_language_id) + check_owner + check_max_repo_creation end + def check_owner + @owner = Owner.find_by(id: user_id) + raise "user_id值无效." if user_id && owner.blank? + end + + def check_max_repo_creation + return unless owner.is_a?(Organization) + return if owner.max_repo_creation <= -1 + raise "已超过组织设置最大仓库数" if owner.max_repo_creation == owner.num_projects + end end diff --git a/app/models/owner.rb b/app/models/owner.rb index d4194c32..1d537a1e 100644 --- a/app/models/owner.rb +++ b/app/models/owner.rb @@ -59,6 +59,7 @@ # class Owner < ApplicationRecord + self.abstract_class = true self.table_name = "users" include ProjectAbility diff --git a/app/models/user.rb b/app/models/user.rb index 1cb6670c..5bfe3b6e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -137,7 +137,6 @@ class User < Owner # 关注 # has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 # has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 - has_many :watchers, as: :watchable, dependent: :destroy has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy diff --git a/app/queries/projects/list_my_query.rb b/app/queries/projects/list_my_query.rb index ba521e90..8ad0d0b0 100644 --- a/app/queries/projects/list_my_query.rb +++ b/app/queries/projects/list_my_query.rb @@ -17,15 +17,12 @@ class Projects::ListMyQuery < ApplicationQuery projects = Project.visible end - if params[:is_public].present? - projects = projects.is_private.members_projects(user.id) if params[:is_public].to_s == "private" - projects = projects.visible.members_projects(user.id) if params[:is_public].to_s == "public" - end - if params[:category].blank? projects = projects.members_projects(user.id) elsif params[:category].to_s == "join" - projects = projects.where.not(user_id: user.id).members_projects(user.id) + normal_projects = projects.where.not(user_id: user.id).members_projects(user.id).to_sql + org_projects = projects.joins(team_projects: [team: :team_users]).where(team_users: {user_id: user.id}).to_sql + projects = Project.from("( #{ normal_projects} UNION #{ org_projects } ) AS projects").distinct elsif params[:category].to_s == "manage" projects = projects.where(user_id: user.id) elsif params[:category].to_s == "watched" #我关注的 @@ -39,6 +36,11 @@ class Projects::ListMyQuery < ApplicationQuery # projects = projects.is_private.joins(:members).where(members: { user_id: user.id }) end + if params[:is_public].present? + projects = projects.is_private if params[:is_public].to_s == "private" + projects = projects.visible if params[:is_public].to_s == "public" + end + if params[:project_type].to_s === "common" projects = projects.common elsif params[:project_type].to_s === "mirror" diff --git a/app/services/gitea/organization/get_service.rb b/app/services/gitea/organization/get_service.rb new file mode 100644 index 00000000..c193bafb --- /dev/null +++ b/app/services/gitea/organization/get_service.rb @@ -0,0 +1,21 @@ +class Gitea::Organization::GetService < Gitea::ClientService + attr_reader :org + + def initialize(org) + @org = org + end + + def call + response = get(url, params) + render_status(response) + end + + private + def params + Hash.new.merge(token: org.gitea_token) + end + + def url + "/orgs/#{org.login}".freeze + end +end \ No newline at end of file diff --git a/app/services/projects/migrate_service.rb b/app/services/projects/migrate_service.rb index ff0c0643..2f7725db 100644 --- a/app/services/projects/migrate_service.rb +++ b/app/services/projects/migrate_service.rb @@ -44,7 +44,7 @@ class Projects::MigrateService < ApplicationService hidden: project_secretion[:hidden], identifier: params[:repository_name], mirror_url: params[:clone_addr], - user_id: user.id, + user_id: params[:user_id], login: params[:auth_username], password: params[:auth_password], is_mirror: params[:is_mirror] diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index f9b5c570..b32b2481 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -1,5 +1,5 @@ class Projects::TransferService < ApplicationService - attr_accessor :project, :owner, :new_owner + attr_accessor :project, :owner, :new_owner, :gitea_repo def initialize(project, new_owner) @project = project @@ -12,6 +12,7 @@ class Projects::TransferService < ApplicationService ActiveRecord::Base.transaction do gitea_update_owner update_owner + update_repo_url update_visit_teams end @@ -25,6 +26,10 @@ class Projects::TransferService < ApplicationService project.update!(user_id: new_owner.id) end + def update_repo_url + project.repository.update!(url: @gitea_repo["clone_url"]) + end + def update_visit_teams if new_owner.is_a?(Organization) new_owner.teams.where(includes_all_project: true).each do |team| @@ -37,7 +42,7 @@ class Projects::TransferService < ApplicationService def gitea_update_owner begin - Gitea::Repository::TransferService.call(owner&.gitea_token, owner&.login, project.identifier, new_owner&.login) + @gitea_repo = Gitea::Repository::TransferService.call(owner&.gitea_token, owner&.login, project.identifier, new_owner&.login) rescue Exception => e Rails.logger.info("##### Project transfer_service, gitea transfer error #{e}") end diff --git a/app/services/repositories/migrate_service.rb b/app/services/repositories/migrate_service.rb index e2f520ae..156777cc 100644 --- a/app/services/repositories/migrate_service.rb +++ b/app/services/repositories/migrate_service.rb @@ -28,7 +28,7 @@ class Repositories::MigrateService < ApplicationService { clone_addr: params[:mirror_url], repo_name: params[:identifier], - uid: user.gitea_uid, + uid: project&.owner&.gitea_uid, private: params[:hidden], mirror: wrapper_mirror || false, auth_username: params[:login], diff --git a/lib/tasks/sync_org_mirror_repo.rake b/lib/tasks/sync_org_mirror_repo.rake new file mode 100644 index 00000000..547b09d8 --- /dev/null +++ b/lib/tasks/sync_org_mirror_repo.rake @@ -0,0 +1,48 @@ +# 执行示例 bundle exec rake sync_org_mirror_repo:init_org_gitea_uid +# RAILS_ENV=production bundle exec rake sync_org_mirror_repo:init_org_gitea_uid +# + +namespace :sync_org_mirror_repo do + desc "更新组织gitea_uid" + task init_org_gitea_uid: :environment do + puts "=========begin to init organization gitea_uid==========" + need_init_orgs = Organization.where(gitea_uid: nil) + puts "=========need init count is [#{need_init_orgs.size}]==========" + need_init_orgs.find_each do |org| + puts "=== fix org name is [#{org.name}] ===" + gitea_org = Gitea::Organization::GetService.call(org) + if gitea_org[:status] == 404 + org.destroy + next + end + org.update(gitea_uid: gitea_org["id"]) + end + puts "========end to init organization gitea_uid===========" + end + + desc "同步组织创建失败的镜像项目" + task fix_mirror_repo: :environment do + puts "========begin to fix mirror repository =========" + need_fix_repos = Repository.joins(:mirror, project: :owner) + .where.not(mirrors: {id: nil}) + .where(users: {type: 'Organization'}) + need_fix_repos.find_each do |repo| + next if repo.user_id == repo.project&.user_id + puts "=== fix repository owner is [#{repo&.project&.owner&.login}] ===" + puts "=== fix repository identifier is [#{repo.identifier}] ===" + Gitea::Repository::DeleteService.call(repo.project.owner, repo.identifier) + gitea_repository_params = { + clone_addr: repo.mirror_url, + repo_name: repo.identifier, + uid: repo.project.owner.gitea_uid, + private: repo.hidden, + mirror: ActiveModel::Type::Boolean.new.cast(repo.is_mirror) || false, + auth_username: repo.login, + auth_password: repo.password + } + MigrateRemoteRepositoryJob.perform_later(repo.id, repo.project&.owner&.gitea_token, gitea_repository_params) + repo.update_columns(user_id: repo.project&.user_id) + end + puts "========end to fix mirror repository =========" + end +end \ No newline at end of file