From f094fe1799100a0fe3e500e8c0ca4e303cd3f808 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 19 Jan 2021 19:02:51 +0800 Subject: [PATCH] =?UTF-8?q?[ADD]=E7=BB=84=E7=BB=87=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/concerns/paginate_helper.rb | 14 +++-- .../organizations/base_controller.rb | 11 +++- .../organization_users_controller.rb | 10 +-- .../organizations/organizations_controller.rb | 7 +-- .../organizations/projects_controller.rb | 32 ++++++++++ .../organizations/team_projects_controller.rb | 56 +++++++++++++++++ .../organizations/team_users_controller.rb | 13 ++-- .../organizations/teams_controller.rb | 6 +- app/controllers/owners_controller.rb | 12 ++++ app/controllers/projects/teams_controller.rb | 10 +++ app/controllers/projects_controller.rb | 2 +- app/forms/projects/create_form.rb | 6 +- app/helpers/application_helper.rb | 2 +- app/models/concerns/project_operable.rb | 41 ++++++++++-- app/models/organization.rb | 34 +++++++++- app/models/organization_user.rb | 5 +- app/models/owner.rb | 62 ++++++++++++++++++- app/models/team.rb | 7 +++ app/models/team_project.rb | 4 +- .../organization/repository/create_service.rb | 25 ++++++++ .../team_project/create_service.rb | 24 +++++++ .../team_project/delete_service.rb | 24 +++++++ app/services/organizations/create_service.rb | 2 +- .../organizations/teams/create_service.rb | 3 +- .../organizations/teams/update_service.rb | 3 +- app/services/repositories/create_service.rb | 24 ++++--- .../projects/index.json.jbuilder | 7 +++ app/views/owners/index.json.jbuilder | 7 +++ app/views/projects/teams/index.json.jbuilder | 4 ++ config/routes.rb | 4 ++ ...0210111065934_create_organization_users.rb | 1 - 31 files changed, 406 insertions(+), 56 deletions(-) create mode 100644 app/controllers/organizations/projects_controller.rb create mode 100644 app/controllers/organizations/team_projects_controller.rb create mode 100644 app/controllers/owners_controller.rb create mode 100644 app/controllers/projects/teams_controller.rb create mode 100644 app/services/gitea/organization/repository/create_service.rb create mode 100644 app/services/gitea/organization/team_project/create_service.rb create mode 100644 app/services/gitea/organization/team_project/delete_service.rb create mode 100644 app/views/organizations/projects/index.json.jbuilder create mode 100644 app/views/owners/index.json.jbuilder create mode 100644 app/views/projects/teams/index.json.jbuilder diff --git a/app/controllers/concerns/paginate_helper.rb b/app/controllers/concerns/paginate_helper.rb index 7233adebf..638a32426 100644 --- a/app/controllers/concerns/paginate_helper.rb +++ b/app/controllers/concerns/paginate_helper.rb @@ -1,12 +1,14 @@ module PaginateHelper - def paginate(objs, **opts) - page = params[:page].to_i <= 0 ? 1 : params[:page].to_i - per_page = params[:per_page].to_i > 0 && params[:per_page].to_i < 50 ? params[:per_page].to_i : opts[:per_page] || 20 - if objs.is_a?(Array) - Kaminari.paginate_array(objs).page(page).per(per_page) + def 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 + + if relation.is_a?(Array) + Kaminari.paginate_array(relation).page(page).per(limit) else - objs.page(page).per(per_page) + relation.page(page).per(limit) end end end \ No newline at end of file diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index e475d19b9..9178f458a 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -1,10 +1,15 @@ class Organizations::BaseController < ApplicationController include ApplicationHelper + include PaginateHelper protected - def organization_owner - @organization.team_users.joins(:team).where(teams: {authorize: 'owner'}).take.user + def can_edit_org? + current_user.admin? || @organization.is_owner?(current_user.id) + end + + def check_user_can_edit_org + tip_exception("您没有权限进行该操作") unless can_edit_org? end def org_limited_condition @@ -16,7 +21,7 @@ class Organizations::BaseController < ApplicationController end def team_not_found_condition - @team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user) + @team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user.id) end def user_mark diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 562c754bf..6c3afa963 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -1,7 +1,6 @@ class Organizations::OrganizationUsersController < Organizations::BaseController before_action :load_organization - before_action :load_operate_user, only: [:destroy] - before_action :load_organization_user, only: [:destroy] + before_action :load_operate_user, :load_organization_user, :check_user_can_edit_org, only: [:destroy] def index @organization_users = @organization.organization_users.includes(:user) @@ -10,11 +9,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController end def destroy - tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_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) + Gitea::Organization::OrganizationUser::DeleteService.call(@organization.gitea_token, @organization.login, @operate_user.login) render_ok end rescue Exception => e @@ -25,10 +24,11 @@ class Organizations::OrganizationUsersController < Organizations::BaseController def quit @organization_user = @organization.organization_users.find_by(user_id: current_user.id) tip_exception("您不在该组织中") if @organization_user.nil? + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(current_user) 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) + Gitea::Organization::OrganizationUser::DeleteService.call(@organization.gitea_token, @organization.login, current_user.login) render_ok end rescue Exception => e diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 93ec7c4e1..458fb94a8 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -2,6 +2,7 @@ class Organizations::OrganizationsController < Organizations::BaseController before_action :require_login, except: [:index, :show] before_action :convert_base64_image!, only: [:create, :update] before_action :load_organization, only: [:show, :update, :destroy] + before_action :check_user_can_edit_org, only: [:update, :destroy] def index if current_user.logged? @@ -29,12 +30,11 @@ 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.reload) + Gitea::Organization::UpdateService.call(@organization.gitea_token, login, @organization.reload) Util.write_file(@image, avatar_path(@organization)) if params[:image].present? end rescue Exception => e @@ -44,9 +44,8 @@ class Organizations::OrganizationsController < Organizations::BaseController def destroy 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) + Gitea::Organization::DeleteService.call(@organization.gitea_token, @organization.login) @organization.destroy! end render_ok diff --git a/app/controllers/organizations/projects_controller.rb b/app/controllers/organizations/projects_controller.rb new file mode 100644 index 000000000..eb6371f72 --- /dev/null +++ b/app/controllers/organizations/projects_controller.rb @@ -0,0 +1,32 @@ +class Organizations::ProjectsController < Organizations::BaseController + before_action :load_organization + + def index + public_projects_sql = @organization.projects.where(is_public: true).to_sql + private_projects_sql = @organization.projects + .where(is_public: false) + .joins(team_projects: {team: :team_users}) + .where(team_users: {user_id: current_user.id}).to_sql + @projects = Project.from("( #{ public_projects_sql} UNION #{ private_projects_sql } ) AS projects") + + @projects = @projects.ransack(name_or_identifier_cont: params[:search]).result if params[:search].present? + @projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}") + @projects = paginate(@projects) + 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 sort + params.fetch(:sort_by, "updated_on") + end + + def sort_direction + params.fetch(:sort_direction, "desc") + end +end \ No newline at end of file diff --git a/app/controllers/organizations/team_projects_controller.rb b/app/controllers/organizations/team_projects_controller.rb new file mode 100644 index 000000000..a2242989d --- /dev/null +++ b/app/controllers/organizations/team_projects_controller.rb @@ -0,0 +1,56 @@ +class Organizations::TeamProjectsController < Organizations::BaseController + before_action :load_organization + before_action :load_team + before_action :load_operate_project, :check_user_can_edit_org, only: [:create, :destroy] + before_action :load_team_project, only: [:destroy] + + def index + @team_projects = @team.team_projects + + @team_projects = paginate(@team_projects) + end + + def create + ActiveRecord::Base.transaction do + @team_project = TeamProject.build(@organization.id, @team.id, @operate_project.id) + Gitea::Organization::TeamProject::CreateService.call(@organization.gitea_token, @team.gtid, @organization.login, @operate_project.identifier) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + ActiveRecord::Base.transaction do + @team_projects.destroy! + Gitea::Organization::TeamProject::DeleteService.call(@organization.gitea_token, @team.gtid, @organization.login, @operate_project.identifier) + 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_project + @operate_project = Project.find_by(name: params[:id]) || Project.find_by(identifier: params[:id]) + tip_exception("项目不存在") if @operate_project.nil? + end + + def load_team_project + @team_project = TeamProject.find_by(organization_id: @organization.id, team_id: @team.id, project_id: @operate_project.id) + tip_exception("组织团队项目不存在") if @team_project.nil? + 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 index 6097331f6..1529aa360 100644 --- a/app/controllers/organizations/team_users_controller.rb +++ b/app/controllers/organizations/team_users_controller.rb @@ -2,6 +2,7 @@ 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] + before_action :check_user_can_edit_org, only: [:create, :destroy] def index @team_users = @team.team_users @@ -10,11 +11,10 @@ class Organizations::TeamUsersController < Organizations::BaseController 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) + Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login) end rescue Exception => e uid_logger_error(e.message) @@ -22,11 +22,10 @@ class Organizations::TeamUsersController < Organizations::BaseController end def destroy - tip_exception("您没有权限进行该操作") unless @organization.is_owner?(current_user) - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @team.num_users == 1 + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user) ActiveRecord::Base.transaction do @team_user.destroy! - Gitea::Organization::TeamUser::DeleteService.call(current_user.gitea_token, @team.gtid, @operate_user.login) + Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login) render_ok end rescue Exception => e @@ -37,10 +36,10 @@ class Organizations::TeamUsersController < Organizations::BaseController 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 + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(current_user) ActiveRecord::Base.transaction do @team_user.destroy! - Gitea::Organization::TeamUser::DeleteService.call(organization_owner.gitea_token, @team.gtid, current_user.login) + Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, current_user.login) render_ok end rescue Exception => e diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 56b11a9fc..5e6185d19 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -1,6 +1,7 @@ class Organizations::TeamsController < Organizations::BaseController before_action :load_organization before_action :load_team, only: [:show, :update, :destroy] + before_action :check_user_can_edit_org, only: [:create, :update, :destroy] def index if @organization.is_owner?(current_user) @@ -16,7 +17,6 @@ class Organizations::TeamsController < Organizations::BaseController 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) @@ -24,7 +24,6 @@ class Organizations::TeamsController < Organizations::BaseController 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) @@ -32,9 +31,8 @@ class Organizations::TeamsController < Organizations::BaseController 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) + Gitea::Organization::Team::DeleteService.call(@organization.gitea_token, @team.gtid) @team.destroy! end render_ok diff --git a/app/controllers/owners_controller.rb b/app/controllers/owners_controller.rb new file mode 100644 index 000000000..97444f7a4 --- /dev/null +++ b/app/controllers/owners_controller.rb @@ -0,0 +1,12 @@ +class OwnersController < ApplicationController + before_action :require_login + + def index + @owners = [] + @owners += [current_user] + @owners += Organization.joins(team_users: :team) + .where(team_users: {user_id: current_user.id}, + teams: {can_create_org_project: true}) + .distinct + end +end \ No newline at end of file diff --git a/app/controllers/projects/teams_controller.rb b/app/controllers/projects/teams_controller.rb new file mode 100644 index 000000000..d5b7ea1e8 --- /dev/null +++ b/app/controllers/projects/teams_controller.rb @@ -0,0 +1,10 @@ +class Projects::TeamsController < Projects::BaseController + def index + if @project.owner.is_a?(Organization) + @teams = @project.owner.teams + else + @teams = Team.none + end + @teams = paginate(@teams) + end +end \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 0a26110d6..bf6c213f1 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -163,7 +163,7 @@ class ProjectsController < ApplicationController private def project_params params.permit(:user_id, :name, :description, :repository_name, - :project_category_id, :project_language_id, :license_id, :ignore_id) + :project_category_id, :project_language_id, :license_id, :ignore_id, :private) end def mirror_params diff --git a/app/forms/projects/create_form.rb b/app/forms/projects/create_form.rb index 39c372309..c4c7f6f63 100644 --- a/app/forms/projects/create_form.rb +++ b/app/forms/projects/create_form.rb @@ -7,7 +7,7 @@ class Projects::CreateForm < BaseForm :project_category_id, :project_language_id, presence: true validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } - validate :check_ignore, :check_license + validate :check_ignore, :check_license, :check_owner validate do check_project_category(project_category_id) check_project_language(project_language_id) @@ -20,4 +20,8 @@ class Projects::CreateForm < BaseForm def check_ignore raise "ignore_id值无效." if ignore_id && Ignore.find_by(id: ignore_id).blank? end + + def check_owner + raise "user_id值无效." if user_id && Owner.find_by(id: user_id).blank? + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 75532188e..30953bf57 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -143,7 +143,7 @@ module ApplicationHelper def url_to_avatar(source) if File.exist?(disk_filename(source&.class, source&.id)) ctime = File.ctime(disk_filename(source.class, source.id)).to_i - if source.class.to_s == 'User' + if %w(User Organization).include?(source.class.to_s) File.join(relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}" else File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}" diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb index f05ed164e..a45049882 100644 --- a/app/models/concerns/project_operable.rb +++ b/app/models/concerns/project_operable.rb @@ -8,6 +8,7 @@ module ProjectOperable 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 end def add_member!(user_id, role_name='Developer') @@ -21,7 +22,13 @@ module ProjectOperable end def member?(user_id) - members.exists?(user_id: user_id) + if owner.is_a?(User) + members.exists?(user_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 # 除了项目创建者本身 @@ -35,22 +42,46 @@ module ProjectOperable end def owner?(user) - self.owner == user + if owner.is_a?(User) + self.owner == user + elsif owner.is_a?(Organization) + owner.is_owner?(user.id) + else + false + end end # 项目管理员(包含项目拥有者),权限:仓库设置、仓库可读可写 def manager?(user) - managers.exists?(user_id: user.id) + if owner.is_a?(User) + managers.exists?(user_id: user.id) + elsif owner.is_a?(Organization) + managers.exists?(user_id: user.id) || owner.is_admin?(user.id) + else + false + end end # 项目开发者,可读可写权限 def develper?(user) - developers.exists?(user_id: user.id) + if owner.is_a?(User) + developers.exists?(user_id: user.id) + elsif owner.is_a?(Organization) + developers.exists?(user_id: user.id) || owner.is_write?(user.id) + else + false + end end # 报告者,只有可读权限 def reporter?(user) - reporters.exists?(user_id: user.id) + if owner.is_a?(User) + reporters.exists?(user_id: user.id) + elsif owner.is_a?(Organization) + reporters.exists?(user_id: user.id) || owner.is_read?(user.id) + else + false + end end def set_developer_role(member) diff --git a/app/models/organization.rb b/app/models/organization.rb index 928f16c3a..7e7cbba92 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -77,8 +77,38 @@ class Organization < Owner self.create!(login: name, gitea_token: gitea_token) end - def is_owner?(user) - team_users.joins(:team).where(user_id: user.id, teams: {authorize: %w(owner)}).present? + def is_owner?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(owner)}).present? end + def is_admin?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(admin owner)}).present? + end + + def is_write?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(write admin owner)}).present? + end + + def is_read?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(read write admin owner)}).present? + end + + # 是不是所有者团队的最后一个成员 + def is_owner_team_last_one?(user_id) + owner_team_users = team_users.joins(:team).where(teams: {authorize: %w(owner)}) + owner_team_users.pluck(:user_id).include?(user_id) && owner_team_users.size == 1 + end + + def real_name + login + end + + def show_real_name + name = lastname + firstname + if name.blank? + nickname.blank? ? login : nickname + else + name + end + end end diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index dd8790235..a2ec890ce 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -5,7 +5,6 @@ # id :integer not null, primary key # user_id :integer # organization_id :integer -# is_creator :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # @@ -22,10 +21,10 @@ class OrganizationUser < ApplicationRecord validates :user_id, uniqueness: {scope: :organization_id} - def self.build(organization_id, user_id, is_creator = false) + def self.build(organization_id, user_id) 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) + self.create!(organization_id: organization_id, user_id: user_id) end def teams diff --git a/app/models/owner.rb b/app/models/owner.rb index 9805b34fc..e058ab564 100644 --- a/app/models/owner.rb +++ b/app/models/owner.rb @@ -1,3 +1,63 @@ +# == Schema Information +# +# Table name: users +# +# id :integer not null, primary key +# login :string(255) default(""), not null +# hashed_password :string(40) default(""), not null +# firstname :string(30) default(""), not null +# lastname :string(255) default(""), not null +# mail :string(60) +# admin :boolean default("0"), not null +# status :integer default("1"), not null +# last_login_on :datetime +# language :string(5) default("") +# auth_source_id :integer +# created_on :datetime +# updated_on :datetime +# type :string(255) +# identity_url :string(255) +# mail_notification :string(255) default(""), not null +# salt :string(64) +# gid :integer +# visits :integer default("0") +# excellent_teacher :integer default("0") +# excellent_student :integer default("0") +# phone :string(255) +# authentication :boolean default("0") +# grade :integer default("0") +# experience :integer default("0") +# nickname :string(255) +# show_realname :boolean default("1") +# professional_certification :boolean default("0") +# ID_number :string(255) +# certification :integer default("0") +# homepage_teacher :boolean default("0") +# homepage_engineer :boolean default("0") +# is_test :integer default("0") +# ecoder_user_id :integer default("0") +# business :boolean default("0") +# profile_completed :boolean default("0") +# laboratory_id :integer +# platform :string(255) default("0") +# gitea_token :string(255) +# gitea_uid :integer +# is_shixun_marker :boolean default("0") +# is_sync_pwd :boolean default("1") +# watchers_count :integer default("0") +# devops_step :integer default("0") +# +# Indexes +# +# index_users_on_ecoder_user_id (ecoder_user_id) +# index_users_on_homepage_engineer (homepage_engineer) +# index_users_on_homepage_teacher (homepage_teacher) +# index_users_on_laboratory_id (laboratory_id) +# index_users_on_login (login) +# index_users_on_mail (mail) +# index_users_on_type (type) +# + class Owner < ApplicationRecord self.table_name = "users" @@ -6,4 +66,4 @@ class Owner < ApplicationRecord has_many :projects, foreign_key: :user_id, dependent: :destroy has_many :repositories, foreign_key: :user_id, dependent: :destroy -end \ No newline at end of file +end diff --git a/app/models/team.rb b/app/models/team.rb index 125517bab..382019f77 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -40,4 +40,11 @@ class Team < ApplicationRecord can_create_org_project: can_create_org_project) end + def setup_team_project! + return unless includes_all_project + organization.projects.each do |project| + TeamProject.build(organization.id, id, project.id) + end + end + end diff --git a/app/models/team_project.rb b/app/models/team_project.rb index 75c62b488..ae2e43152 100644 --- a/app/models/team_project.rb +++ b/app/models/team_project.rb @@ -22,9 +22,9 @@ class TeamProject < ApplicationRecord belongs_to :project belongs_to :team, counter_cache: :num_projects - validates :project_id, uniqueness: {scope: :organization_id} + validates :project_id, uniqueness: {scope: [:organization_id, :team_id]} def self.build(organization_id, team_id, project_id) - self.create!(organization_id: organization_id, team_id: team_id, project_id: project_id) + self.find_or_create_by!(organization_id: organization_id, team_id: team_id, project_id: project_id) end end diff --git a/app/services/gitea/organization/repository/create_service.rb b/app/services/gitea/organization/repository/create_service.rb new file mode 100644 index 000000000..060a8ab05 --- /dev/null +++ b/app/services/gitea/organization/repository/create_service.rb @@ -0,0 +1,25 @@ +class Gitea::Organization::Repository::CreateService < Gitea::ClientService + attr_reader :token, :org_name, :params + + def initialize(token, org_name, params) + @token = token + @org_name = org_name + @params = params + end + + def call + response = post(url, request_params) + render_201_response(response) + end + + private + + def request_params + create_params = params.merge(readme: "readme") + Hash.new.merge(token: token, data: create_params) + end + + def url + "/orgs/#{org_name}/repos".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team_project/create_service.rb b/app/services/gitea/organization/team_project/create_service.rb new file mode 100644 index 000000000..562480ac5 --- /dev/null +++ b/app/services/gitea/organization/team_project/create_service.rb @@ -0,0 +1,24 @@ +class Gitea::Organization::TeamProject::CreateService < Gitea::ClientService + attr_reader :token, :gtid, :org_name, :repo_name + + def initialize(token, gtid, org_name, repo_name) + @token = token + @gtid = gtid + @org_name = org_name + @repo_name = repo_name + 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}/repos/#{org_name}/#{repo_name}".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/team_project/delete_service.rb b/app/services/gitea/organization/team_project/delete_service.rb new file mode 100644 index 000000000..9d59f5e2f --- /dev/null +++ b/app/services/gitea/organization/team_project/delete_service.rb @@ -0,0 +1,24 @@ +class Gitea::Organization::TeamProject::DeleteService < Gitea::ClientService + attr_reader :token, :gtid, :org_name, :repo_name + + def initialize(token, gtid, org_name, repo_name) + @token = token + @gtid = gtid + @org_name = org_name + @repo_name = repo_name + end + + def call + response = delete(url, params) + render_status(response) + end + + private + def params + Hash.new.merge(token: token) + end + + def url + "/teams/#{gtid}/repos/#{org_name}/#{repo_name}".freeze + end +end \ No newline at end of file diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index 3da2951ff..5fcbda12d 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -63,7 +63,7 @@ class Organizations::CreateService < ApplicationService end def create_gitea_org - @gitea_organization = Gitea::Organization::CreateService.call(user.gitea_token, organization) + @gitea_organization = Gitea::Organization::CreateService.call(@organization.gitea_token, organization) end def sync_owner_team_gtid diff --git a/app/services/organizations/teams/create_service.rb b/app/services/organizations/teams/create_service.rb index 9a26e3c65..81ad78772 100644 --- a/app/services/organizations/teams/create_service.rb +++ b/app/services/organizations/teams/create_service.rb @@ -16,6 +16,7 @@ class Organizations::Teams::CreateService < ApplicationService create_units create_gitea_team sync_team_gtid + team.setup_team_project! end Rails.logger.info("######Team create_service end######") @@ -64,7 +65,7 @@ class Organizations::Teams::CreateService < ApplicationService end def create_gitea_team - @gitea_team = Gitea::Organization::Team::CreateService.call(user.gitea_token, org, team) + @gitea_team = Gitea::Organization::Team::CreateService.call(org.gitea_token, org, team) end def sync_team_gtid diff --git a/app/services/organizations/teams/update_service.rb b/app/services/organizations/teams/update_service.rb index d7599d0cf..71c82c40b 100644 --- a/app/services/organizations/teams/update_service.rb +++ b/app/services/organizations/teams/update_service.rb @@ -14,6 +14,7 @@ class Organizations::Teams::UpdateService < ApplicationService update_team(update_params) update_units team.reload + team.setup_team_project! update_gitea_team end Rails.logger.info("######Team update_service end######") @@ -53,6 +54,6 @@ class Organizations::Teams::UpdateService < ApplicationService end def update_gitea_team - Gitea::Organization::Team::UpdateService.call(user.gitea_token, team) + Gitea::Organization::Team::UpdateService.call(team&.organization&.gitea_token, team) end end \ No newline at end of file diff --git a/app/services/repositories/create_service.rb b/app/services/repositories/create_service.rb index 9458e513f..f6aecdd95 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -1,5 +1,6 @@ class Repositories::CreateService < ApplicationService attr_reader :user, :project, :params + attr_accessor :repository, :gitea_repository def initialize(user, project, params) @project = project @@ -10,10 +11,10 @@ class Repositories::CreateService < ApplicationService def call @repository = Repository.new(repository_params) ActiveRecord::Base.transaction do - if @repository.save! - gitea_repository = Gitea::Repository::CreateService.new(user.gitea_token, gitea_repository_params).call - sync_project(@repository, gitea_repository) - sync_repository(@repository, gitea_repository) + if repository.save! + create_gitea_repository + sync_project + sync_repository # if project.project_type == "common" # chain_params = { # type: "create", @@ -29,7 +30,7 @@ class Repositories::CreateService < ApplicationService else Rails.logger.info("#############___________create_repository_erros______###########{@repository.errors.messages}") end - @repository + repository end rescue => e puts "create repository service error: #{e.message}" @@ -38,7 +39,16 @@ class Repositories::CreateService < ApplicationService private - def sync_project(repository, gitea_repository) + def create_gitea_repository + if project.owner.is_a?(User) + @gitea_repository = Gitea::Repository::CreateService.new(user.gitea_token, gitea_repository_params).call + elsif project.owner.is_a?(Organization) + @gitea_repository = Gitea::Organization::Repository::CreateService.call(user.gitea_token, project.owner.login, gitea_repository_params) + project.owner.teams.map{|t|t.setup_team_project!} + end + end + + def sync_project if gitea_repository project.update_columns( gpid: gitea_repository["id"], @@ -47,7 +57,7 @@ class Repositories::CreateService < ApplicationService end end - def sync_repository(repository, gitea_repository) + def sync_repository repository.update_columns(url: remote_repository_url,) if gitea_repository end diff --git a/app/views/organizations/projects/index.json.jbuilder b/app/views/organizations/projects/index.json.jbuilder new file mode 100644 index 000000000..739f870ba --- /dev/null +++ b/app/views/organizations/projects/index.json.jbuilder @@ -0,0 +1,7 @@ +json.total_count @projects.total_count +json.projects @projects.each do |project| + json.(project, :name, :identifier, :description, :forked_count, :praises_count) + json.praised project.praised_by?(current_user) + json.last_update_time render_unix_time(project.updated_on) + json.time_ago time_from_now(project.updated_on) +end \ No newline at end of file diff --git a/app/views/owners/index.json.jbuilder b/app/views/owners/index.json.jbuilder new file mode 100644 index 000000000..677aff71a --- /dev/null +++ b/app/views/owners/index.json.jbuilder @@ -0,0 +1,7 @@ +json.total_count @owners.size +json.owners @owners.each do |owner| + json.id owner.id + json.type owner.type + json.name owner.login + json.avatar_url url_to_avatar(owner) +end \ No newline at end of file diff --git a/app/views/projects/teams/index.json.jbuilder b/app/views/projects/teams/index.json.jbuilder new file mode 100644 index 000000000..f6f7572b8 --- /dev/null +++ b/app/views/projects/teams/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @teams.total_count +json.teams @teams.each do |team| + json.(team, :id, :name, :authorize) +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 8442994d4..20d5fbe68 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,8 @@ Rails.application.routes.draw do put 'commons/unhidden', to: 'commons#unhidden' delete 'commons/delete', to: 'commons#delete' + resources :owners, only: [:index] + scope module: :organizations do resources :organizations, except: [:edit, :new] do resources :organization_users, only: [:index, :destroy] do @@ -118,6 +120,7 @@ Rails.application.routes.draw do end resources :team_projects, only: [:index, :create, :destroy] do ;end end + resources :projects, only: [:index] end end @@ -512,6 +515,7 @@ Rails.application.routes.draw do end scope module: :projects do + resources :teams, only: [:index] scope do get( '/blob/*id/diff', diff --git a/db/migrate/20210111065934_create_organization_users.rb b/db/migrate/20210111065934_create_organization_users.rb index 166a8ff8d..3300d9330 100644 --- a/db/migrate/20210111065934_create_organization_users.rb +++ b/db/migrate/20210111065934_create_organization_users.rb @@ -3,7 +3,6 @@ class CreateOrganizationUsers < ActiveRecord::Migration[5.2] create_table :organization_users do |t| t.references :user t.references :organization - t.boolean :is_creator, comment: "是否为创建者", default: false t.timestamps end