From 2434ca96817284817f04f6a36026df5cfb7d4e8a Mon Sep 17 00:00:00 2001 From: viletyy Date: Mon, 11 Jan 2021 17:44:11 +0800 Subject: [PATCH 01/24] =?UTF-8?q?[ADD]=E7=BB=84=E7=BB=87=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + .../organizations/base_controller.rb | 11 +++ .../organizations/organizations_controller.rb | 74 ++++++++++++++++ app/models/laboratory.rb | 5 ++ app/models/laboratory_setting.rb | 4 + app/models/organization.rb | 88 +++++++++++++++++++ app/models/organization_extension.rb | 36 ++++++++ app/models/organization_user.rb | 25 ++++++ app/models/team.rb | 44 ++++++++++ app/models/team_project.rb | 28 ++++++ app/models/team_unit.rb | 36 ++++++++ app/models/team_user.rb | 28 ++++++ app/models/user.rb | 1 + app/services/gitea/client_service.rb | 3 +- .../gitea/organization/create_service.rb | 43 +++++++++ .../gitea/organization/delete_service.rb | 23 +++++ .../gitea/organization/update_service.rb | 44 ++++++++++ app/services/organizations/create_service.rb | 28 ++++++ .../organizations/_detail.json.jbuilder | 9 ++ .../organizations/create.json.jbuilder | 1 + .../organizations/index.json.jbuilder | 3 + .../organizations/update.json.jbuilder | 1 + config/routes.rb | 13 +++ ...0210111065934_create_organization_users.rb | 11 +++ ...11065954_create_organization_extensions.rb | 15 ++++ db/migrate/20210111093008_create_teams.rb | 17 ++++ .../20210111093016_create_team_projects.rb | 11 +++ .../20210111093024_create_team_users.rb | 10 +++ .../20210111093200_create_team_units.rb | 11 +++ public/react/build | 1 + spec/models/organization_extension_spec.rb | 5 ++ spec/models/organization_user_spec.rb | 5 ++ spec/models/team_project_spec.rb | 5 ++ spec/models/team_spec.rb | 5 ++ spec/models/team_unit_spec.rb | 5 ++ spec/models/team_user_spec.rb | 5 ++ 36 files changed, 655 insertions(+), 1 deletion(-) create mode 100644 app/controllers/organizations/base_controller.rb create mode 100644 app/controllers/organizations/organizations_controller.rb create mode 100644 app/models/organization.rb create mode 100644 app/models/organization_extension.rb create mode 100644 app/models/organization_user.rb create mode 100644 app/models/team.rb create mode 100644 app/models/team_project.rb create mode 100644 app/models/team_unit.rb create mode 100644 app/models/team_user.rb create mode 100644 app/services/gitea/organization/create_service.rb create mode 100644 app/services/gitea/organization/delete_service.rb create mode 100644 app/services/gitea/organization/update_service.rb create mode 100644 app/services/organizations/create_service.rb create mode 100644 app/views/organizations/organizations/_detail.json.jbuilder create mode 100644 app/views/organizations/organizations/create.json.jbuilder create mode 100644 app/views/organizations/organizations/index.json.jbuilder create mode 100644 app/views/organizations/organizations/update.json.jbuilder create mode 100644 db/migrate/20210111065934_create_organization_users.rb create mode 100644 db/migrate/20210111065954_create_organization_extensions.rb create mode 100644 db/migrate/20210111093008_create_teams.rb create mode 100644 db/migrate/20210111093016_create_team_projects.rb create mode 100644 db/migrate/20210111093024_create_team_users.rb create mode 100644 db/migrate/20210111093200_create_team_units.rb create mode 160000 public/react/build create mode 100644 spec/models/organization_extension_spec.rb create mode 100644 spec/models/organization_user_spec.rb create mode 100644 spec/models/team_project_spec.rb create mode 100644 spec/models/team_spec.rb create mode 100644 spec/models/team_unit_spec.rb create mode 100644 spec/models/team_user_spec.rb diff --git a/README.md b/README.md index 8f5a897e0..b75fcd647 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,8 @@ http://localhost:3000/ ### API - [API](api_document.md) +- [API](showdoc.com.cn) + 账号:forgeplus@admin.com 密码:forge123 ## 贡献代码 diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb new file mode 100644 index 000000000..d0b9594dc --- /dev/null +++ b/app/controllers/organizations/base_controller.rb @@ -0,0 +1,11 @@ +class Organizations::BaseController < ApplicationController + include ApplicationHelper + + def load_organization + @organization = Organization.find_by(login: params[:id]) || Organization.find_by(id: params[:id]) + + render_not_found if @organization.nil? + + @organization + end +end \ No newline at end of file diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb new file mode 100644 index 000000000..16079bcc5 --- /dev/null +++ b/app/controllers/organizations/organizations_controller.rb @@ -0,0 +1,74 @@ +class Organizations::OrganizationsController < Organizations::BaseController + before_action :require_login, except: [:index] + before_action :convert_base64_image!, only: [:create, :update] + before_action :load_organization, only: [:update, :destroy] + + 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}) + else + @organizations = Organization.with_visibility("common") + end + kaminary_array_paginate(@organizations) + end + + def create + ActiveRecord::Base.transaction do + @organization = Organizations::CreateService.call(current_user, organization_params) + Util.write_file(@image, avatar_path(@organization)) if params[:image].present? + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def update + 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) + Util.write_file(@image, avatar_path(@organization)) if params[:image].present? + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + render_unauthorized unless current_user.check_password?(password) + render_forbidden("您没有权限进行该操作") unless @organization.check_owner?(current_user) + ActiveRecord::Base.transaction do + Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login) + @organization.destroy! + end + render_ok + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def convert_base64_image! + max_size = EduSetting.get('upload_avatar_max_size') + @image = Util.convert_base64_image(params[:image].to_s.strip, max_size: max_size) + rescue Base64ImageConverter::Error => ex + render_error(ex.message) + end + + def avatar_path(organization) + ApplicationController.helpers.disk_filename(organization.class, organization.id) + end + + def organization_params + params.permit(:name, :description, :website, :location, + :repo_admin_change_team_access, :visibility, + :max_repo_creation) + end + + def password + params.fetch(:password, "") + end + +end \ No newline at end of file diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 73002a841..699800c92 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -11,6 +11,11 @@ # sync_subject :boolean default("0") # sync_shixun :boolean default("0") # +# Indexes +# +# index_laboratories_on_identifier (identifier) UNIQUE +# index_laboratories_on_school_id (school_id) +# class Laboratory < ApplicationRecord belongs_to :school, optional: true diff --git a/app/models/laboratory_setting.rb b/app/models/laboratory_setting.rb index 5013dd547..61c677def 100644 --- a/app/models/laboratory_setting.rb +++ b/app/models/laboratory_setting.rb @@ -6,6 +6,10 @@ # laboratory_id :integer # config :text(65535) # +# Indexes +# +# index_laboratory_settings_on_laboratory_id (laboratory_id) +# class LaboratorySetting < ApplicationRecord belongs_to :laboratory diff --git a/app/models/organization.rb b/app/models/organization.rb new file mode 100644 index 000000000..c3ebda1d7 --- /dev/null +++ b/app/models/organization.rb @@ -0,0 +1,88 @@ +# == 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 Organization < ApplicationRecord + self.table_name = "users" + default_scope { where(type: "Organization") } + + has_one :organization_extension, dependent: :destroy + has_many :teams, dependent: :destroy + has_many :organization_users, dependent: :destroy + has_many :team_users, dependent: :destroy + + validates :login, presence: true + validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false + + delegate :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, to: :organization_extension, allow_nil: true + + scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } + + def self.build(name) + self.create!(login: name) + end + + def owner_team + teams.where(authorize: 4).take + end + + def check_owner?(user) + owner_team.team_users.where(user_id: user.id).present? + end +end diff --git a/app/models/organization_extension.rb b/app/models/organization_extension.rb new file mode 100644 index 000000000..982e38f6b --- /dev/null +++ b/app/models/organization_extension.rb @@ -0,0 +1,36 @@ +# == Schema Information +# +# Table name: organization_extensions +# +# id :integer not null, primary key +# organization_id :integer +# description :string(255) +# website :string(255) +# location :string(255) +# repo_admin_change_team_access :boolean default("0") +# visibility :integer default("0") +# max_repo_creation :integer default("-1") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_organization_extensions_on_organization_id (organization_id) +# + +class OrganizationExtension < ApplicationRecord + + belongs_to :organization + + enum visibility: {common: 0, limited: 1, privacy: 2} + + def self.build(organization_id, description, website, location, repo_admin_change_team_access, visibility, max_repo_creation) + self.create!(organization_id: organization_id, + description: description, + website: website, + location: location, + repo_admin_change_team_access: repo_admin_change_team_access, + visibility: visibility, + max_repo_creation: max_repo_creation) + end +end diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb new file mode 100644 index 000000000..cfd5cc9f5 --- /dev/null +++ b/app/models/organization_user.rb @@ -0,0 +1,25 @@ +# == Schema Information +# +# Table name: organization_users +# +# 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 +# +# Indexes +# +# index_organization_users_on_organization_id (organization_id) +# index_organization_users_on_user_id (user_id) +# + +class OrganizationUser < ApplicationRecord + + belongs_to :organization + + def self.build(organization_id, user_id, is_creator) + self.create!(organization_id: organization_id, user_id: user_id, is_creator: is_creator) + end +end diff --git a/app/models/team.rb b/app/models/team.rb new file mode 100644 index 000000000..a37cade73 --- /dev/null +++ b/app/models/team.rb @@ -0,0 +1,44 @@ +# == Schema Information +# +# Table name: teams +# +# id :integer not null, primary key +# organization_id :integer +# name :string(255) +# description :string(255) +# authorize :integer default("0") +# num_projects :integer default("0") +# num_users :integer default("0") +# includes_all_project :boolean default("0") +# can_create_org_project :boolean default("0") +# gtid :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_teams_on_organization_id (organization_id) +# + +class Team < ApplicationRecord + + belongs_to :organization + has_many :team_projects, dependent: :destroy + has_many :team_units, dependent: :destroy + has_many :team_users, dependent: :destroy + + 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) + self.create!(organization_id: organization_id, + name: name, + description: description, + authorize: authorize, + includes_all_project: includes_all_project, + 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 new file mode 100644 index 000000000..7ae475d8c --- /dev/null +++ b/app/models/team_project.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: team_projects +# +# id :integer not null, primary key +# organization_id :integer +# project_id :integer +# team_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_team_projects_on_organization_id (organization_id) +# index_team_projects_on_project_id (project_id) +# index_team_projects_on_team_id (team_id) +# + +class TeamProject < ApplicationRecord + + belongs_to :organization + belongs_to :project + belongs_to :team, counter_cache: :num_projects + + def self.build(organization_id, team_id, project_id) + self.create!(organization_id: organization_id, team_id: team_id, project_id: project_id) + end +end diff --git a/app/models/team_unit.rb b/app/models/team_unit.rb new file mode 100644 index 000000000..f655f01fd --- /dev/null +++ b/app/models/team_unit.rb @@ -0,0 +1,36 @@ +# == Schema Information +# +# Table name: team_units +# +# id :integer not null, primary key +# organization_id :integer +# team_id :integer +# unit_type :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_team_units_on_organization_id (organization_id) +# index_team_units_on_team_id (team_id) +# + +class TeamUnit < ApplicationRecord + + belongs_to :organization + belongs_to :team + + enum unit_type: {code: 1, issue: 2, pull_request: 3, releases: 4} + + validates :unit_type, uniqueness: { scope: [:organization_id, :team_id]} + + def self.build(organization_id, team_id, unit_type) + 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 new file mode 100644 index 000000000..57cef55f3 --- /dev/null +++ b/app/models/team_user.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: team_users +# +# id :integer not null, primary key +# organization_id :integer +# team_id :integer +# user_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_team_users_on_organization_id (organization_id) +# index_team_users_on_team_id (team_id) +# index_team_users_on_user_id (user_id) +# + +class TeamUser < ApplicationRecord + + belongs_to :organization + belongs_to :team, counter_cache: :num_users + belongs_to :user + + def self.build(organization_id, user_id, team_id) + self.create!(organization_id: organization_id, user_id: user_id, team_id: team_id) + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 5ea57880d..a94a30fdf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -59,6 +59,7 @@ # class User < ApplicationRecord + default_scope {where(type: %w(User AnonymousUser))} extend Enumerize include Watchable diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb index 1e9de823c..1c13bc424 100644 --- a/app/services/gitea/client_service.rb +++ b/app/services/gitea/client_service.rb @@ -132,7 +132,8 @@ class Gitea::ClientService < ApplicationService when 204 puts "[gitea] " - raise Error, "[gitea] delete ok" + # raise Error, "[gitea] delete ok" + {status: 204} when 409 message = "创建失败,请检查该分支合并是否已存在" raise Error, mark + message diff --git a/app/services/gitea/organization/create_service.rb b/app/services/gitea/organization/create_service.rb new file mode 100644 index 000000000..4b20b2264 --- /dev/null +++ b/app/services/gitea/organization/create_service.rb @@ -0,0 +1,43 @@ +class Gitea::Organization::CreateService < Gitea::ClientService + attr_reader :token, :org + + def initialize(token, org) + @token = token + @org = org + end + + def call + response = post(url, request_params) + render_status(response) + end + + private + def request_params + create_params = { + username: 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 + } + Hash.new.merge(token: token, data: create_params) + end + + def visibility(visibility) + case visibility + when "common" + "public" + when "limited" + "limited" + when "privacy" + "private" + else + "public" + end + end + + def url + "/orgs".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/organization/delete_service.rb b/app/services/gitea/organization/delete_service.rb new file mode 100644 index 000000000..e72820133 --- /dev/null +++ b/app/services/gitea/organization/delete_service.rb @@ -0,0 +1,23 @@ +class Gitea::Organization::DeleteService < Gitea::ClientService + attr_reader :token, :name + + def initialize(token, name) + @token = token + @name = name + end + + def call + response = delete(url, params) + render_status(response) + end + + private + + def params + Hash.new.merge(token: token) + end + + def url + "/orgs/#{name}".freeze + end +end diff --git a/app/services/gitea/organization/update_service.rb b/app/services/gitea/organization/update_service.rb new file mode 100644 index 000000000..7655d5f38 --- /dev/null +++ b/app/services/gitea/organization/update_service.rb @@ -0,0 +1,44 @@ +class Gitea::Organization::UpdateService < Gitea::ClientService + attr_reader :token, :login, :org + + def initialize(token, login, org) + @token = token + @login = login + @org = org + end + + def call + response = patch(url, request_params) + render_status(response) + end + + private + def request_params + update_params = { + username: 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 + } + Hash.new.merge(token: token, data: update_params) + end + + def visibility(visibility) + case visibility + when "common" + "public" + when "limited" + "limited" + when "privacy" + "private" + else + "public" + end + end + + def url + "/orgs/#{login}".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 new file mode 100644 index 000000000..c0fceeb02 --- /dev/null +++ b/app/services/organizations/create_service.rb @@ -0,0 +1,28 @@ +class Organizations::CreateService < ApplicationService + attr_reader :user, :params + + def initialize(user, params) + @user = user + @params = params + end + + def call + 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, params[:description], params[:website], + params[:location], params[:repo_admin_change_team_access], + params[:visibility], params[: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) + + Rails.logger.info("######Organization create_service end######") + end + @organization + end +end \ No newline at end of file diff --git a/app/views/organizations/organizations/_detail.json.jbuilder b/app/views/organizations/organizations/_detail.json.jbuilder new file mode 100644 index 000000000..3e2a00b6d --- /dev/null +++ b/app/views/organizations/organizations/_detail.json.jbuilder @@ -0,0 +1,9 @@ +json.id organization.id +json.name organization.login +json.description organization.description +json.website organization.website +json.location organization.location +json.repo_admin_change_team_access organization.repo_admin_change_team_access +json.visibility organization.visibility +json.max_repo_creation organization.max_repo_creation +json.avatar_url url_to_avatar(organization) \ No newline at end of file diff --git a/app/views/organizations/organizations/create.json.jbuilder b/app/views/organizations/organizations/create.json.jbuilder new file mode 100644 index 000000000..55de73daf --- /dev/null +++ b/app/views/organizations/organizations/create.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", organization: @organization \ No newline at end of file diff --git a/app/views/organizations/organizations/index.json.jbuilder b/app/views/organizations/organizations/index.json.jbuilder new file mode 100644 index 000000000..b9066223f --- /dev/null +++ b/app/views/organizations/organizations/index.json.jbuilder @@ -0,0 +1,3 @@ +json.organizations @organizations do |organization| + json.partial! "detail", organization: organization +end diff --git a/app/views/organizations/organizations/update.json.jbuilder b/app/views/organizations/organizations/update.json.jbuilder new file mode 100644 index 000000000..55de73daf --- /dev/null +++ b/app/views/organizations/organizations/update.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", organization: @organization \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 041b84454..851a58150 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,19 @@ Rails.application.routes.draw do put 'commons/unhidden', to: 'commons#unhidden' delete 'commons/delete', to: 'commons#delete' + scope module: :organizations do + resources :organizations do + + end + resources :teams do + resources :team_users do + end + resources :team_projects do + + end + end + end + resources :issues, except: [:index, :new,:create, :update, :edit, :destroy] do resources :journals, only: [:index, :create, :destroy, :edit, :update] do member do diff --git a/db/migrate/20210111065934_create_organization_users.rb b/db/migrate/20210111065934_create_organization_users.rb new file mode 100644 index 000000000..166a8ff8d --- /dev/null +++ b/db/migrate/20210111065934_create_organization_users.rb @@ -0,0 +1,11 @@ +class CreateOrganizationUsers < ActiveRecord::Migration[5.2] + def change + create_table :organization_users do |t| + t.references :user + t.references :organization + t.boolean :is_creator, comment: "是否为创建者", default: false + + t.timestamps + end + end +end diff --git a/db/migrate/20210111065954_create_organization_extensions.rb b/db/migrate/20210111065954_create_organization_extensions.rb new file mode 100644 index 000000000..b99a43579 --- /dev/null +++ b/db/migrate/20210111065954_create_organization_extensions.rb @@ -0,0 +1,15 @@ +class CreateOrganizationExtensions < ActiveRecord::Migration[5.2] + def change + create_table :organization_extensions do |t| + t.references :organization + t.string :description, comment: "组织描述" + t.string :website, comment: "组织官方网站" + t.string :location, comment: "组织地区" + t.boolean :repo_admin_change_team_access, comment: "项目管理员是否可以添加或移除团队的访问权限", default: false + t.integer :visibility, comment: "组织可见性", default: 0 + t.integer :max_repo_creation, comment: "组织最大仓库数", default: -1 + + t.timestamps + end + end +end diff --git a/db/migrate/20210111093008_create_teams.rb b/db/migrate/20210111093008_create_teams.rb new file mode 100644 index 000000000..486835e9d --- /dev/null +++ b/db/migrate/20210111093008_create_teams.rb @@ -0,0 +1,17 @@ +class CreateTeams < ActiveRecord::Migration[5.2] + def change + create_table :teams do |t| + t.references :organization + t.string :name, comment: "团队名称" + t.string :description, comment: "团队描述" + t.integer :authorize, comment: "团队权限", default: 0 + t.integer :num_projects, comment: "团队项目数量", default: 0 + t.integer :num_users, comment: "团队成员数量", default: 0 + t.boolean :includes_all_project, comment: "团队是否拥有所有项目", default: false + t.boolean :can_create_org_project, comment: "团队是否能创建项目", default: false + t.integer :gtid, comment: "团队在gitea里的id" + + t.timestamps + end + end +end diff --git a/db/migrate/20210111093016_create_team_projects.rb b/db/migrate/20210111093016_create_team_projects.rb new file mode 100644 index 000000000..1bb35cf16 --- /dev/null +++ b/db/migrate/20210111093016_create_team_projects.rb @@ -0,0 +1,11 @@ +class CreateTeamProjects < ActiveRecord::Migration[5.2] + def change + create_table :team_projects do |t| + t.references :organization + t.references :project + t.references :team + + t.timestamps + end + end +end diff --git a/db/migrate/20210111093024_create_team_users.rb b/db/migrate/20210111093024_create_team_users.rb new file mode 100644 index 000000000..4e3579e5d --- /dev/null +++ b/db/migrate/20210111093024_create_team_users.rb @@ -0,0 +1,10 @@ +class CreateTeamUsers < ActiveRecord::Migration[5.2] + def change + create_table :team_users do |t| + t.references :organization + t.references :team + t.references :user + t.timestamps + end + end +end diff --git a/db/migrate/20210111093200_create_team_units.rb b/db/migrate/20210111093200_create_team_units.rb new file mode 100644 index 000000000..62948732c --- /dev/null +++ b/db/migrate/20210111093200_create_team_units.rb @@ -0,0 +1,11 @@ +class CreateTeamUnits < ActiveRecord::Migration[5.2] + def change + create_table :team_units do |t| + t.references :organization + t.references :team + t.integer :unit_type, comment: "访问单元类型" + + t.timestamps + end + end +end diff --git a/public/react/build b/public/react/build new file mode 160000 index 000000000..6348a15cd --- /dev/null +++ b/public/react/build @@ -0,0 +1 @@ +Subproject commit 6348a15cdb954862dc1b7b5f045a432bcfde7dc4 diff --git a/spec/models/organization_extension_spec.rb b/spec/models/organization_extension_spec.rb new file mode 100644 index 000000000..fe155b50b --- /dev/null +++ b/spec/models/organization_extension_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe OrganizationExtension, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/organization_user_spec.rb b/spec/models/organization_user_spec.rb new file mode 100644 index 000000000..bdf82dc5c --- /dev/null +++ b/spec/models/organization_user_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe OrganizationUser, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/team_project_spec.rb b/spec/models/team_project_spec.rb new file mode 100644 index 000000000..217e27d1f --- /dev/null +++ b/spec/models/team_project_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TeamProject, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/team_spec.rb b/spec/models/team_spec.rb new file mode 100644 index 000000000..8fddabf72 --- /dev/null +++ b/spec/models/team_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Team, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/team_unit_spec.rb b/spec/models/team_unit_spec.rb new file mode 100644 index 000000000..7c903b8a0 --- /dev/null +++ b/spec/models/team_unit_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TeamUnit, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/team_user_spec.rb b/spec/models/team_user_spec.rb new file mode 100644 index 000000000..86d4cece7 --- /dev/null +++ b/spec/models/team_user_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe TeamUser, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From c278ed186339c93439d30030fe0321665b567a3d Mon Sep 17 00:00:00 2001 From: viletyy Date: Wed, 13 Jan 2021 15:43:30 +0800 Subject: [PATCH 02/24] [FIX] --- app/controllers/application_controller.rb | 8 +++++ .../organizations/base_controller.rb | 11 +++++++ .../organizations/organizations_controller.rb | 11 +++++-- app/services/organizations/create_service.rb | 30 +++++++++++++++++-- .../organizations/show.json.jbuilder | 1 + 5 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 app/views/organizations/organizations/show.json.jbuilder diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9d6efdcb6..7bf88abc5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -680,6 +680,14 @@ class ApplicationController < ActionController::Base relation.page(page).per(limit) end + def kaminary_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 + + Kaminari.paginate_array(relation).page(page).per(limit) + end + def strf_time(time) time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S") end diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index d0b9594dc..346f996e7 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -4,8 +4,19 @@ class Organizations::BaseController < ApplicationController def load_organization @organization = Organization.find_by(login: params[:id]) || Organization.find_by(id: params[:id]) + @organization = nil if limited_condition || privacy_condition + render_not_found if @organization.nil? @organization end + + private + def limited_condition + @organization.organization_extension.limited? && !current_user.logged? + end + + def privacy_condition + @organization.organization_extension.privacy? && @organization.organization_users.where(user_id: current_user.id).blank? + 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 16079bcc5..ccdb68ecc 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -1,16 +1,21 @@ class Organizations::OrganizationsController < Organizations::BaseController - before_action :require_login, except: [:index] + before_action :require_login, except: [:index, :show] before_action :convert_base64_image!, only: [:create, :update] - before_action :load_organization, only: [:update, :destroy] + before_action :load_organization, only: [:show, :update, :destroy] 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) else @organizations = Organization.with_visibility("common") + kaminari_paginate(@organizations) end - kaminary_array_paginate(@organizations) + end + + def show + end def create diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index c0fceeb02..f09b9f833 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -11,9 +11,9 @@ class Organizations::CreateService < ApplicationService Rails.logger.info("######params #{params}######") ActiveRecord::Base.transaction do @organization = Organization.build(params[:name]) - org_extension = OrganizationExtension.build(@organization.id, params[:description], params[:website], - params[:location], params[:repo_admin_change_team_access], - params[:visibility], params[:max_repo_creation]) + 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) @@ -25,4 +25,28 @@ class Organizations::CreateService < ApplicationService end @organization end + + def description + params[:description].present? ? params[:description] : nil + end + + def website + params[:website].present? ? params[:website] : nil + end + + def location + params[:location].present? ? params[:location] : nil + end + + def repo_admin_change_team_access + params[:repo_admin_change_team_access].present? ? params[:repo_admin_change_team_access] : false + end + + def visibility + params[:visibility].present? ? params[:visibility] : "common" + end + + def max_repo_creation + params[:max_repo_creation].present? ? params[:max_repo_creation] : -1 + end end \ No newline at end of file diff --git a/app/views/organizations/organizations/show.json.jbuilder b/app/views/organizations/organizations/show.json.jbuilder new file mode 100644 index 000000000..55de73daf --- /dev/null +++ b/app/views/organizations/organizations/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", organization: @organization \ No newline at end of file From 7f309edc910dd3bcf0bff4c5deb955486eac253d Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 15 Jan 2021 14:55:52 +0800 Subject: [PATCH 03/24] =?UTF-8?q?[ADD]=E7=BB=84=E7=BB=87=E3=80=81=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E5=9B=A2=E9=98=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 2 +- .../organizations/base_controller.rb | 23 +++--- .../organization_users_controller.rb | 55 ++++++++++++++ .../organizations/organizations_controller.rb | 23 ++++-- .../organizations/team_users_controller.rb | 74 +++++++++++++++++++ .../organizations/teams_controller.rb | 62 ++++++++++++++++ .../users/organizations_controller.rb | 14 ++++ app/models/organization.rb | 7 +- app/models/organization_user.rb | 11 ++- app/models/team.rb | 5 +- app/models/team_project.rb | 2 + app/models/team_unit.rb | 7 +- app/models/team_user.rb | 2 + app/models/user.rb | 3 + .../gitea/organization/create_service.rb | 3 +- .../organization_user/delete_service.rb | 23 ++++++ .../gitea/organization/team/create_service.rb | 50 +++++++++++++ .../gitea/organization/team/delete_service.rb | 22 ++++++ .../gitea/organization/team/update_service.rb | 49 ++++++++++++ .../organization/team_user/create_service.rb | 23 ++++++ .../organization/team_user/delete_service.rb | 23 ++++++ .../gitea/organization/update_service.rb | 5 +- app/services/organizations/create_service.rb | 46 ++++++++---- .../organizations/teams/create_service.rb | 74 +++++++++++++++++++ .../organizations/teams/update_service.rb | 58 +++++++++++++++ .../organization_users/_detail.json.jbuilder | 6 ++ .../organization_users/index.json.jbuilder | 4 + .../team_users/_detail.json.jbuilder | 4 + .../team_users/create.json.jbuilder | 1 + .../team_users/index.json.jbuilder | 4 + .../organizations/teams/_detail.json.jbuilder | 9 +++ .../organizations/teams/create.json.jbuilder | 1 + .../organizations/teams/index.json.jbuilder | 4 + .../organizations/teams/show.json.jbuilder | 1 + .../organizations/teams/update.json.jbuilder | 1 + .../users/organizations/index.json.jbuilder | 3 + config/routes.rb | 20 +++-- 37 files changed, 667 insertions(+), 57 deletions(-) create mode 100644 app/controllers/organizations/organization_users_controller.rb create mode 100644 app/controllers/organizations/team_users_controller.rb create mode 100644 app/controllers/organizations/teams_controller.rb create mode 100644 app/controllers/users/organizations_controller.rb create mode 100644 app/services/gitea/organization/organization_user/delete_service.rb create mode 100644 app/services/gitea/organization/team/create_service.rb create mode 100644 app/services/gitea/organization/team/delete_service.rb create mode 100644 app/services/gitea/organization/team/update_service.rb create mode 100644 app/services/gitea/organization/team_user/create_service.rb create mode 100644 app/services/gitea/organization/team_user/delete_service.rb create mode 100644 app/services/organizations/teams/create_service.rb create mode 100644 app/services/organizations/teams/update_service.rb create mode 100644 app/views/organizations/organization_users/_detail.json.jbuilder create mode 100644 app/views/organizations/organization_users/index.json.jbuilder create mode 100644 app/views/organizations/team_users/_detail.json.jbuilder create mode 100644 app/views/organizations/team_users/create.json.jbuilder create mode 100644 app/views/organizations/team_users/index.json.jbuilder create mode 100644 app/views/organizations/teams/_detail.json.jbuilder create mode 100644 app/views/organizations/teams/create.json.jbuilder create mode 100644 app/views/organizations/teams/index.json.jbuilder create mode 100644 app/views/organizations/teams/show.json.jbuilder create mode 100644 app/views/organizations/teams/update.json.jbuilder create mode 100644 app/views/users/organizations/index.json.jbuilder 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] From 31858a79e35360a792cea75f5bcbc4085d17d568 Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 15 Jan 2021 17:19:34 +0800 Subject: [PATCH 04/24] =?UTF-8?q?[FIX]=E6=88=90=E5=91=98=E7=BB=86=E8=8A=82?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/organizations/_user_detail.json.jbuilder | 8 ++++++++ .../organization_users/_detail.json.jbuilder | 5 +++-- app/views/organizations/team_users/_detail.json.jbuilder | 5 +++-- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 app/views/organizations/_user_detail.json.jbuilder diff --git a/app/views/organizations/_user_detail.json.jbuilder b/app/views/organizations/_user_detail.json.jbuilder new file mode 100644 index 000000000..0fa35215a --- /dev/null +++ b/app/views/organizations/_user_detail.json.jbuilder @@ -0,0 +1,8 @@ +json.user_id user.id +json.login user.login +json.name user.full_name +json.mail user.mail +json.identity user.identity +json.watched current_user.watched?(user) +# json.email user.mail # 邮箱原则上不暴露的,如果实在需要的话只能对某些具体的接口公开 +json.image_url url_to_avatar(user) diff --git a/app/views/organizations/organization_users/_detail.json.jbuilder b/app/views/organizations/organization_users/_detail.json.jbuilder index 20696efcd..90426a61a 100644 --- a/app/views/organizations/organization_users/_detail.json.jbuilder +++ b/app/views/organizations/organization_users/_detail.json.jbuilder @@ -1,6 +1,7 @@ json.id org_user.id json.user do - json.partial! "/users/user", user: org_user.user + json.partial! "organizations/user_detail", user: org_user.user end -json.team_names org_user.teams.pluck(:name) \ No newline at end of file +json.team_names org_user.teams.pluck(:name) +json.created_at org_user.created_at.strftime("%Y-%m-%d") \ No newline at end of file diff --git a/app/views/organizations/team_users/_detail.json.jbuilder b/app/views/organizations/team_users/_detail.json.jbuilder index c6c93e779..6bb6bf78a 100644 --- a/app/views/organizations/team_users/_detail.json.jbuilder +++ b/app/views/organizations/team_users/_detail.json.jbuilder @@ -1,4 +1,5 @@ json.id team_user.id json.user do - json.partial! "/users/user", user: team_user.user -end \ No newline at end of file + json.partial! "organizations/user_detail", user: team_user.user +end +json.created_at team_user.created_at.strftime("%Y-%m-%d") \ No newline at end of file From 1dc43a23b76211162458e0d4208a980049681932 Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 15 Jan 2021 18:28:38 +0800 Subject: [PATCH 05/24] =?UTF-8?q?[FIX]=E4=B8=BA=E7=BB=84=E7=BB=87=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E9=A1=B9=E7=9B=AE=E5=81=9A=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../version_releases_controller.rb | 2 +- app/jobs/sync_mirrored_repository_job.rb | 2 +- app/models/organization.rb | 7 +- app/models/owner.rb | 9 ++ app/models/project.rb | 144 +++++++++--------- app/models/repository.rb | 2 +- app/models/user.rb | 7 +- app/services/organizations/create_service.rb | 2 +- app/services/projects/fork_service.rb | 2 +- 9 files changed, 90 insertions(+), 87 deletions(-) create mode 100644 app/models/owner.rb diff --git a/app/controllers/version_releases_controller.rb b/app/controllers/version_releases_controller.rb index a9e7fa63a..1b56236a4 100644 --- a/app/controllers/version_releases_controller.rb +++ b/app/controllers/version_releases_controller.rb @@ -124,7 +124,7 @@ class VersionReleasesController < ApplicationController private def set_user - @user = @repository.user + @user = @repository.owner end def find_version diff --git a/app/jobs/sync_mirrored_repository_job.rb b/app/jobs/sync_mirrored_repository_job.rb index 8184ddee5..f0617146a 100644 --- a/app/jobs/sync_mirrored_repository_job.rb +++ b/app/jobs/sync_mirrored_repository_job.rb @@ -5,7 +5,7 @@ class SyncMirroredRepositoryJob < ApplicationJob repo = Repository.find_by(id: repo_id) current_user = User.find_by(id: user_id) return if repo.blank? || current_user.blank? - result = Gitea::Repository::SyncMirroredService.new(repo.user.login, repo.identifier, token: current_user.gitea_token).call + result = Gitea::Repository::SyncMirroredService.new(repo.owner.login, repo.identifier, token: current_user.gitea_token).call repo&.mirror.set_status! if result[:status] === 200 end end diff --git a/app/models/organization.rb b/app/models/organization.rb index 5a8594925..928f16c3a 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -58,8 +58,7 @@ # index_users_on_type (type) # -class Organization < ApplicationRecord - self.table_name = "users" +class Organization < Owner default_scope { where(type: "Organization") } has_one :organization_extension, dependent: :destroy @@ -74,8 +73,8 @@ class Organization < ApplicationRecord scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } - def self.build(name) - self.create!(login: name) + def self.build(name, gitea_token=nil) + self.create!(login: name, gitea_token: gitea_token) end def is_owner?(user) diff --git a/app/models/owner.rb b/app/models/owner.rb new file mode 100644 index 000000000..9805b34fc --- /dev/null +++ b/app/models/owner.rb @@ -0,0 +1,9 @@ +class Owner < ApplicationRecord + self.table_name = "users" + + include ProjectOperable + include ProjectAbility + + 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 diff --git a/app/models/project.rb b/app/models/project.rb index 4b9e72e19..dd7babd17 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,73 +1,73 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) default(""), not null -# description :text(4294967295) -# homepage :string(255) default("") -# is_public :boolean default("1"), not null -# parent_id :integer -# created_on :datetime -# updated_on :datetime -# identifier :string(255) -# status :integer default("1"), not null -# lft :integer -# rgt :integer -# inherit_members :boolean default("0"), not null -# project_type :integer default("0") -# hidden_repo :boolean default("0"), not null -# attachmenttype :integer default("1") -# user_id :integer -# dts_test :integer default("0") -# enterprise_name :string(255) -# organization_id :integer -# project_new_type :integer -# gpid :integer -# forked_from_project_id :integer -# forked_count :integer default("0") -# publish_resource :integer default("0") -# visits :integer default("0") -# hot :integer default("0") -# invite_code :string(255) -# qrcode :string(255) -# qrcode_expiretime :integer default("0") -# script :text(65535) -# training_status :integer default("0") -# rep_identifier :string(255) -# project_category_id :integer -# project_language_id :integer -# license_id :integer -# ignore_id :integer -# praises_count :integer default("0") -# watchers_count :integer default("0") -# issues_count :integer default("0") -# pull_requests_count :integer default("0") -# language :string(255) -# versions_count :integer default("0") -# issue_tags_count :integer default("0") -# closed_issues_count :integer default("0") -# open_devops :boolean default("0") -# gitea_webhook_id :integer -# open_devops_count :integer default("0") -# recommend :boolean default("0") -# platform :integer default("0") -# -# Indexes -# -# index_projects_on_forked_from_project_id (forked_from_project_id) -# index_projects_on_identifier (identifier) -# index_projects_on_is_public (is_public) -# index_projects_on_lft (lft) -# index_projects_on_name (name) -# index_projects_on_platform (platform) -# index_projects_on_project_type (project_type) -# index_projects_on_recommend (recommend) -# index_projects_on_rgt (rgt) -# index_projects_on_status (status) -# index_projects_on_updated_on (updated_on) -# - +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) default(""), not null +# description :text(4294967295) +# homepage :string(255) default("") +# is_public :boolean default("1"), not null +# parent_id :integer +# created_on :datetime +# updated_on :datetime +# identifier :string(255) +# status :integer default("1"), not null +# lft :integer +# rgt :integer +# inherit_members :boolean default("0"), not null +# project_type :integer default("0") +# hidden_repo :boolean default("0"), not null +# attachmenttype :integer default("1") +# user_id :integer +# dts_test :integer default("0") +# enterprise_name :string(255) +# organization_id :integer +# project_new_type :integer +# gpid :integer +# forked_from_project_id :integer +# forked_count :integer default("0") +# publish_resource :integer default("0") +# visits :integer default("0") +# hot :integer default("0") +# invite_code :string(255) +# qrcode :string(255) +# qrcode_expiretime :integer default("0") +# script :text(65535) +# training_status :integer default("0") +# rep_identifier :string(255) +# project_category_id :integer +# project_language_id :integer +# license_id :integer +# ignore_id :integer +# praises_count :integer default("0") +# watchers_count :integer default("0") +# issues_count :integer default("0") +# pull_requests_count :integer default("0") +# language :string(255) +# versions_count :integer default("0") +# issue_tags_count :integer default("0") +# closed_issues_count :integer default("0") +# open_devops :boolean default("0") +# gitea_webhook_id :integer +# open_devops_count :integer default("0") +# recommend :boolean default("0") +# platform :integer default("0") +# +# Indexes +# +# index_projects_on_forked_from_project_id (forked_from_project_id) +# index_projects_on_identifier (identifier) +# index_projects_on_is_public (is_public) +# index_projects_on_lft (lft) +# index_projects_on_name (name) +# index_projects_on_platform (platform) +# index_projects_on_project_type (project_type) +# index_projects_on_recommend (recommend) +# index_projects_on_rgt (rgt) +# index_projects_on_status (status) +# index_projects_on_updated_on (updated_on) +# + class Project < ApplicationRecord include Matchable include Publicable @@ -85,7 +85,7 @@ class Project < ApplicationRecord belongs_to :ignore, optional: true belongs_to :license, optional: true - belongs_to :owner, class_name: 'User', foreign_key: :user_id, optional: true + belongs_to :owner, class_name: 'Owner', foreign_key: :user_id, optional: true belongs_to :project_category, optional: true , :counter_cache => true belongs_to :project_language, optional: true , :counter_cache => true has_many :project_trends, dependent: :destroy @@ -248,7 +248,7 @@ class Project < ApplicationRecord def self.find_with_namespace(namespace_path, identifier) logger.info "########namespace_path: #{namespace_path} ########identifier: #{identifier} " - user = User.find_by_login namespace_path + user = Owner.find_by_login namespace_path project = user&.projects&.find_by(identifier: identifier) || Project.find_by(identifier: "#{namespace_path}/#{identifier}") return nil if project.blank? diff --git a/app/models/repository.rb b/app/models/repository.rb index be6afcb10..934eaa0e3 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -33,7 +33,7 @@ class Repository < ApplicationRecord self.inheritance_column = nil # FIX The single-table inheritance mechanism failed belongs_to :project, :touch => true - belongs_to :user, optional: true + belongs_to :owner, class_name: 'Owner', foreign_key: :user_id, optional: true has_one :mirror, foreign_key: :repo_id has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', foreign_key: :repo_id has_many :version_releases, dependent: :destroy diff --git a/app/models/user.rb b/app/models/user.rb index 4341f0c87..23f957d1a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -58,15 +58,13 @@ # index_users_on_type (type) # -class User < ApplicationRecord +class User < Owner default_scope {where(type: %w(User AnonymousUser))} extend Enumerize include Watchable include Likeable include BaseModel - include ProjectOperable - include ProjectAbility include Droneable # include Searchable::Dependents::User @@ -155,9 +153,6 @@ class User < ApplicationRecord # 项目 has_many :applied_projects, dependent: :destroy - has_many :projects, dependent: :destroy - has_many :repositories, dependent: :destroy - # 教学案例 # has_many :libraries, dependent: :destroy has_many :project_trends, dependent: :destroy diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index da5fdd2d8..3da2951ff 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -47,7 +47,7 @@ class Organizations::CreateService < ApplicationService end def create_org_and_extension - @organization = Organization.build(params[:name]) + @organization = Organization.build(params[:name], user.gitea_token) org_extension = OrganizationExtension.build(organization.id, description, website, location, repo_admin_change_team_access, visibility, max_repo_creation) diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index 3efd3e43c..3204e5fc7 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -20,7 +20,7 @@ class Projects::ForkService < ApplicationService clone_project.save! new_repository = clone_project.repository - new_repository.user = @target_owner + new_repository.owner = @target_owner new_repository.identifier = @project.identifier new_repository.save! From f094fe1799100a0fe3e500e8c0ca4e303cd3f808 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 19 Jan 2021 19:02:51 +0800 Subject: [PATCH 06/24] =?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 From 3f73484596f14a1fb8f3577058c845794dd21f42 Mon Sep 17 00:00:00 2001 From: viletyy Date: Wed, 20 Jan 2021 18:48:28 +0800 Subject: [PATCH 07/24] =?UTF-8?q?[FIX]=E4=B8=80=E4=BA=9B=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=88=9B=E5=BB=BA=E6=9C=80=E5=A4=A7=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=95=B0=E9=87=8F=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [FIX] --- app/controllers/organizations/base_controller.rb | 4 ++++ .../organizations/organizations_controller.rb | 11 ++++++++++- .../organizations/team_projects_controller.rb | 6 ++++-- app/controllers/users/organizations_controller.rb | 13 ++++++++++++- app/forms/projects/create_form.rb | 13 ++++++++++--- app/models/organization.rb | 3 ++- app/models/organization_extension.rb | 4 ++++ app/models/organization_user.rb | 1 + app/models/project.rb | 1 + app/services/organizations/create_service.rb | 2 +- app/services/repositories/create_service.rb | 5 ++++- .../organizations/_detail.json.jbuilder | 2 ++ .../organizations/projects/index.json.jbuilder | 2 +- .../team_projects/_detail.json.jbuilder | 6 ++++++ .../team_projects/create.json.jbuilder | 1 + .../organizations/team_projects/index.json.jbuilder | 4 ++++ ...0081821_add_columns_to_organization_extension.rb | 6 ++++++ 17 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 app/views/organizations/team_projects/_detail.json.jbuilder create mode 100644 app/views/organizations/team_projects/create.json.jbuilder create mode 100644 app/views/organizations/team_projects/index.json.jbuilder create mode 100644 db/migrate/20210120081821_add_columns_to_organization_extension.rb diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index 9178f458a..2e8ae0cf9 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -27,4 +27,8 @@ class Organizations::BaseController < ApplicationController def user_mark params[:username] || params[:id] end + + def project_mark + params[:repo_name] || params[:id] + 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 458fb94a8..e4fda4e8e 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -12,7 +12,8 @@ class Organizations::OrganizationsController < Organizations::BaseController else @organizations = Organization.with_visibility("common") end - @organizations = @organizations.includes(:organization_extension).order(id: :asc) + @organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present? + @organizations = @organizations.includes(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}") @organizations = kaminari_paginate(@organizations) end @@ -82,4 +83,12 @@ class Organizations::OrganizationsController < Organizations::BaseController tip_exception("没有查看组织的权限") if org_limited_condition || org_privacy_condition end + def sort_by + params.fetch(:sort_by, "created_at") + 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 index a2242989d..f221c98db 100644 --- a/app/controllers/organizations/team_projects_controller.rb +++ b/app/controllers/organizations/team_projects_controller.rb @@ -11,6 +11,7 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def create + tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project 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) @@ -21,8 +22,9 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def destroy + tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project ActiveRecord::Base.transaction do - @team_projects.destroy! + @team_project.destroy! Gitea::Organization::TeamProject::DeleteService.call(@organization.gitea_token, @team.gtid, @organization.login, @operate_project.identifier) render_ok end @@ -45,7 +47,7 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def load_operate_project - @operate_project = Project.find_by(name: params[:id]) || Project.find_by(identifier: params[:id]) + @operate_project = Project.find_by(id: project_mark) || Project.find_by(identifier: project_mark) tip_exception("项目不存在") if @operate_project.nil? end diff --git a/app/controllers/users/organizations_controller.rb b/app/controllers/users/organizations_controller.rb index b0bfbd037..721339e84 100644 --- a/app/controllers/users/organizations_controller.rb +++ b/app/controllers/users/organizations_controller.rb @@ -9,6 +9,17 @@ class Users::OrganizationsController < Users::BaseController @organizations = observed_user.organizations.with_visibility("common") end - @organizations = @organizations.includes(:organization_extension).order(id: :asc) + @organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present? + @organizations = @organizations.includes(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}") + @organizations = kaminari_paginate(@organizations) + end + + private + def sort_by + params.fetch(:sort_by, "created_at") + end + + def sort_direction + params.fetch(:sort_direction, "desc") end end \ No newline at end of file diff --git a/app/forms/projects/create_form.rb b/app/forms/projects/create_form.rb index c4c7f6f63..2838996b6 100644 --- a/app/forms/projects/create_form.rb +++ b/app/forms/projects/create_form.rb @@ -1,13 +1,13 @@ class Projects::CreateForm < BaseForm REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, - :project_language_id, :ignore_id, :license_id, :private + :project_language_id, :ignore_id, :license_id, :private, :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: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } - validate :check_ignore, :check_license, :check_owner + validate :check_ignore, :check_license, :check_owner, :check_max_repo_creation validate do check_project_category(project_category_id) check_project_language(project_language_id) @@ -22,6 +22,13 @@ class Projects::CreateForm < BaseForm end def check_owner - raise "user_id值无效." if user_id && Owner.find_by(id: user_id).blank? + @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/organization.rb b/app/models/organization.rb index 7e7cbba92..fb8d94c40 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -69,7 +69,8 @@ class Organization < Owner validates :login, presence: true validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false - delegate :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, to: :organization_extension, allow_nil: true + delegate :description, :website, :location, :repo_admin_change_team_access, + :visibility, :max_repo_creation, :num_projects, :num_users, to: :organization_extension, allow_nil: true scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } diff --git a/app/models/organization_extension.rb b/app/models/organization_extension.rb index 982e38f6b..16797f716 100644 --- a/app/models/organization_extension.rb +++ b/app/models/organization_extension.rb @@ -12,6 +12,8 @@ # max_repo_creation :integer default("-1") # created_at :datetime not null # updated_at :datetime not null +# num_projects :integer default("0") +# num_users :integer default("0") # # Indexes # @@ -21,6 +23,8 @@ class OrganizationExtension < ApplicationRecord belongs_to :organization + has_many :organization_users, foreign_key: :organization_id, primary_key: :organization_id + has_many :projects, foreign_key: :user_id, primary_key: :organization_id enum visibility: {common: 0, limited: 1, privacy: 2} diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index a2ec890ce..cf9e22371 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -17,6 +17,7 @@ class OrganizationUser < ApplicationRecord belongs_to :organization + belongs_to :organization_extension, foreign_key: :organization_id, primary_key: :organization_id, counter_cache: :num_users belongs_to :user validates :user_id, uniqueness: {scope: :organization_id} diff --git a/app/models/project.rb b/app/models/project.rb index dd7babd17..a91cf891d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -86,6 +86,7 @@ class Project < ApplicationRecord belongs_to :ignore, optional: true belongs_to :license, optional: true belongs_to :owner, class_name: 'Owner', foreign_key: :user_id, optional: true + belongs_to :organization_extension, foreign_key: :user_id, primary_key: :organization_id, optional: true, counter_cache: :num_projects belongs_to :project_category, optional: true , :counter_cache => true belongs_to :project_language, optional: true , :counter_cache => true has_many :project_trends, dependent: :destroy diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index 5fcbda12d..02065135b 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -58,7 +58,7 @@ class Organizations::CreateService < ApplicationService 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) + OrganizationUser.build(organization.id, user.id) TeamUser.build(organization.id, user.id, owner_team.id) end diff --git a/app/services/repositories/create_service.rb b/app/services/repositories/create_service.rb index f6aecdd95..9b89490fb 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -44,7 +44,10 @@ class Repositories::CreateService < ApplicationService @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!} + project.owner.teams.each do |team| + next unless team.includes_all_project + TeamProject.build(project.user_id, team.id, project.id) + end end end diff --git a/app/views/organizations/organizations/_detail.json.jbuilder b/app/views/organizations/organizations/_detail.json.jbuilder index 3e2a00b6d..d8dc17e81 100644 --- a/app/views/organizations/organizations/_detail.json.jbuilder +++ b/app/views/organizations/organizations/_detail.json.jbuilder @@ -6,4 +6,6 @@ json.location organization.location json.repo_admin_change_team_access organization.repo_admin_change_team_access json.visibility organization.visibility json.max_repo_creation organization.max_repo_creation +json.num_projects organization.num_projects +json.num_user organization.num_users json.avatar_url url_to_avatar(organization) \ No newline at end of file diff --git a/app/views/organizations/projects/index.json.jbuilder b/app/views/organizations/projects/index.json.jbuilder index 739f870ba..5ade6ad5c 100644 --- a/app/views/organizations/projects/index.json.jbuilder +++ b/app/views/organizations/projects/index.json.jbuilder @@ -1,6 +1,6 @@ json.total_count @projects.total_count json.projects @projects.each do |project| - json.(project, :name, :identifier, :description, :forked_count, :praises_count) + json.(project, :id, :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) diff --git a/app/views/organizations/team_projects/_detail.json.jbuilder b/app/views/organizations/team_projects/_detail.json.jbuilder new file mode 100644 index 000000000..d65021086 --- /dev/null +++ b/app/views/organizations/team_projects/_detail.json.jbuilder @@ -0,0 +1,6 @@ +json.id team_project.id +json.project do + json.owner_name team_project&.project&.owner&.login + json.name team_project&.project&.name + json.identifier team_project&.project&.identifier +end \ No newline at end of file diff --git a/app/views/organizations/team_projects/create.json.jbuilder b/app/views/organizations/team_projects/create.json.jbuilder new file mode 100644 index 000000000..e9f32468c --- /dev/null +++ b/app/views/organizations/team_projects/create.json.jbuilder @@ -0,0 +1 @@ +json.partial! "detail", team_project: @team_project, team: @team, organization: @organization \ No newline at end of file diff --git a/app/views/organizations/team_projects/index.json.jbuilder b/app/views/organizations/team_projects/index.json.jbuilder new file mode 100644 index 000000000..102c042cb --- /dev/null +++ b/app/views/organizations/team_projects/index.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @team_projects.total_count +json.team_projects @team_projects do |team_project| + json.partial! "detail", team_project: team_project, team: @team, organization: @organization +end diff --git a/db/migrate/20210120081821_add_columns_to_organization_extension.rb b/db/migrate/20210120081821_add_columns_to_organization_extension.rb new file mode 100644 index 000000000..96089c9ce --- /dev/null +++ b/db/migrate/20210120081821_add_columns_to_organization_extension.rb @@ -0,0 +1,6 @@ +class AddColumnsToOrganizationExtension < ActiveRecord::Migration[5.2] + def change + add_column :organization_extensions, :num_projects, :integer, default: 0 + add_column :organization_extensions, :num_users, :integer, default: 0 + end +end From 0c58447afb12058e5a5c17736673c55b54028870 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 26 Jan 2021 17:44:04 +0800 Subject: [PATCH 08/24] =?UTF-8?q?[FIX]=E7=BB=84=E7=BB=87=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=A4=B4=E5=83=8F=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A7=8D=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E3=80=81=E9=A1=B9=E7=9B=AE=E8=AF=A6=E6=83=85=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=8B=A5=E6=9C=89=E8=80=85=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [FIX] [FIX] --- .../organizations/base_controller.rb | 9 +++++++ .../organizations/organizations_controller.rb | 17 +++++++++--- app/controllers/projects_controller.rb | 4 +-- app/helpers/projects_helper.rb | 2 ++ app/models/user.rb | 2 +- app/services/organizations/create_service.rb | 26 +++++++++++++++++++ .../projects/index.json.jbuilder | 4 ++- .../projects/_project_detail.json.jbuilder | 2 ++ app/views/repositories/_author.json.jbuilder | 2 ++ 9 files changed, 60 insertions(+), 8 deletions(-) diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index 2e8ae0cf9..580185426 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -31,4 +31,13 @@ class Organizations::BaseController < ApplicationController def project_mark params[:repo_name] || params[:id] end + + private + def limited_condition + @organization.organization_extension.limited? && !current_user.logged? + end + + def privacy_condition + @organization.organization_extension.privacy? && @organization.organization_users.where(user_id: current_user.id).blank? + 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 e4fda4e8e..8ad88a8f0 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -1,6 +1,6 @@ class Organizations::OrganizationsController < Organizations::BaseController before_action :require_login, except: [:index, :show] - before_action :convert_base64_image!, only: [:create, :update] + before_action :convert_image!, only: [:create, :update] before_action :load_organization, only: [:show, :update, :destroy] before_action :check_user_can_edit_org, only: [:update, :destroy] @@ -11,6 +11,7 @@ class Organizations::OrganizationsController < Organizations::BaseController @organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users") else @organizations = Organization.with_visibility("common") + kaminari_paginate(@organizations) end @organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present? @organizations = @organizations.includes(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}") @@ -56,9 +57,17 @@ class Organizations::OrganizationsController < Organizations::BaseController end private - def convert_base64_image! - max_size = EduSetting.get('upload_avatar_max_size') - @image = Util.convert_base64_image(params[:image].to_s.strip, max_size: max_size) + def convert_image! + max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M + if params[:image].class == ActionDispatch::Http::UploadedFile + @image = params[:image] + render_error('请上传文件') if @image.size.zero? + render_error('文件大小超过限制') if @image.size > max_size + else + image = params[:image].to_s.strip + return render_error('请上传正确的图片') if image.blank? + @image = Util.convert_base64_image(image, max_size: max_size) + end rescue Base64ImageConverter::Error => ex render_error(ex.message) end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index bf6c213f1..2939e7fb8 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -11,7 +11,7 @@ class ProjectsController < ApplicationController scope = Projects::ListQuery.call(params) # @projects = kaminari_paginate(scope) - @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, owner: :user_extension) + @projects = paginate scope.includes(:project_category, :project_language, :repository, :project_educoder, :owner) category_id = params[:category_id] @total_count = @@ -128,7 +128,7 @@ class ProjectsController < ApplicationController end def recommend - @projects = Project.recommend.includes(:repository, :project_category, owner: :user_extension).limit(5) + @projects = Project.recommend.includes(:repository, :project_category, :owner).limit(5) end def about diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index c00010b2b..6fbc22eb5 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -61,12 +61,14 @@ module ProjectsHelper { login: project.project_educoder.owner, name: project.project_educoder.owner, + type: 'Educoder', image_url: project.project_educoder.image_url } else { login: @owner.login, name: @owner.real_name, + type: @owner.type, image_url: url_to_avatar(@owner) } end diff --git a/app/models/user.rb b/app/models/user.rb index 23f957d1a..250a9b8b2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -167,7 +167,7 @@ class User < Owner where("LOWER(concat(lastname, firstname, login, mail)) LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank? } - scope :simple_select, -> {select(:id, :login, :lastname,:firstname, :nickname, :gitea_uid)} + scope :simple_select, -> {select(:id, :login, :lastname,:firstname, :nickname, :gitea_uid, :type)} attr_accessor :password, :password_confirmation diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index 02065135b..2727f4c9b 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -11,16 +11,30 @@ class Organizations::CreateService < ApplicationService Rails.logger.info("######Organization create_service begin######") Rails.logger.info("######params #{params}######") ActiveRecord::Base.transaction do +<<<<<<< HEAD create_org_and_extension create_owner_info create_gitea_org sync_owner_team_gtid +======= + @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) +>>>>>>> 38887e6... [FIX] Rails.logger.info("######Organization create_service end######") end @organization end +<<<<<<< HEAD private def description params[:description] @@ -32,6 +46,18 @@ class Organizations::CreateService < ApplicationService def location params[:location] +======= + def description + params[:description].present? ? params[:description] : nil + end + + def website + params[:website].present? ? params[:website] : nil + end + + def location + params[:location].present? ? params[:location] : nil +>>>>>>> 38887e6... [FIX] end def repo_admin_change_team_access diff --git a/app/views/organizations/projects/index.json.jbuilder b/app/views/organizations/projects/index.json.jbuilder index 5ade6ad5c..a663b0c18 100644 --- a/app/views/organizations/projects/index.json.jbuilder +++ b/app/views/organizations/projects/index.json.jbuilder @@ -1,6 +1,8 @@ json.total_count @projects.total_count json.projects @projects.each do |project| - json.(project, :id, :name, :identifier, :description, :forked_count, :praises_count) + json.(project, :id, :name, :identifier, :description, :forked_count, :praises_count, :forked_from_project_id) + json.mirror_url project.repository&.mirror_url + json.type project.numerical_for_project_type 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) diff --git a/app/views/projects/_project_detail.json.jbuilder b/app/views/projects/_project_detail.json.jbuilder index fdbd05dfb..94aee427e 100644 --- a/app/views/projects/_project_detail.json.jbuilder +++ b/app/views/projects/_project_detail.json.jbuilder @@ -18,11 +18,13 @@ json.author do if project.educoder? project_educoder = project.project_educoder json.name project_educoder&.owner + json.type 'Educoder' json.login project_educoder&.repo_name.split('/')[0] json.image_url render_educoder_avatar_url(project.project_educoder) else user = project.owner json.name user.try(:show_real_name) + json.type user&.type json.login user.login json.image_url render_avatar_url(user) end diff --git a/app/views/repositories/_author.json.jbuilder b/app/views/repositories/_author.json.jbuilder index 326920223..1dbcc4ebc 100644 --- a/app/views/repositories/_author.json.jbuilder +++ b/app/views/repositories/_author.json.jbuilder @@ -1,11 +1,13 @@ json.author do if @project.forge? json.login user.login + json.type user&.type json.name user.real_name json.image_url url_to_avatar(user) else json.login @project.project_educoder&.repo_name&.split('/')[0] json.name @project.project_educoder&.owner + json.type 'Educoder' json.image_url @project.project_educoder&.image_url end end From 289d1877d6c4a7c4d7e4929ecf3d467b858b8c41 Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 15 Jan 2021 14:55:52 +0800 Subject: [PATCH 09/24] =?UTF-8?q?[ADD]=E7=BB=84=E7=BB=87=E3=80=81=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E5=9B=A2=E9=98=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../organizations/base_controller.rb | 13 +++++++--- .../organizations/organizations_controller.rb | 2 +- app/models/organization_user.rb | 4 +++ app/services/organizations/create_service.rb | 26 ------------------- .../organizations/teams/create_service.rb | 4 +++ .../organization_users/_detail.json.jbuilder | 2 +- .../team_users/_detail.json.jbuilder | 2 +- 7 files changed, 21 insertions(+), 32 deletions(-) diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index 580185426..8bd4b2dd4 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -32,12 +32,19 @@ class Organizations::BaseController < ApplicationController params[:repo_name] || params[:id] 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/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 8ad88a8f0..2236d95bb 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -11,7 +11,6 @@ class Organizations::OrganizationsController < Organizations::BaseController @organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users") else @organizations = Organization.with_visibility("common") - kaminari_paginate(@organizations) end @organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present? @organizations = @organizations.includes(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}") @@ -32,6 +31,7 @@ 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? diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index cf9e22371..1bf328f19 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -31,4 +31,8 @@ class OrganizationUser < ApplicationRecord def teams organization.teams.joins(:team_users).where(team_users: {user_id: user_id}) end + + def teams + organization.teams.joins(:team_users).where(team_users: {user_id: user_id}) + end end diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index 2727f4c9b..c2ca0f431 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -11,30 +11,16 @@ class Organizations::CreateService < ApplicationService Rails.logger.info("######Organization create_service begin######") Rails.logger.info("######params #{params}######") ActiveRecord::Base.transaction do -<<<<<<< HEAD create_org_and_extension create_owner_info create_gitea_org sync_owner_team_gtid -======= - @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) ->>>>>>> 38887e6... [FIX] Rails.logger.info("######Organization create_service end######") end @organization end -<<<<<<< HEAD private def description params[:description] @@ -44,20 +30,8 @@ class Organizations::CreateService < ApplicationService params[:website] end - def location - params[:location] -======= - def description - params[:description].present? ? params[:description] : nil - end - - def website - params[:website].present? ? params[:website] : nil - end - def location params[:location].present? ? params[:location] : nil ->>>>>>> 38887e6... [FIX] end def repo_admin_change_team_access diff --git a/app/services/organizations/teams/create_service.rb b/app/services/organizations/teams/create_service.rb index 81ad78772..867d41b12 100644 --- a/app/services/organizations/teams/create_service.rb +++ b/app/services/organizations/teams/create_service.rb @@ -65,7 +65,11 @@ class Organizations::Teams::CreateService < ApplicationService end def create_gitea_team +<<<<<<< HEAD @gitea_team = Gitea::Organization::Team::CreateService.call(org.gitea_token, org, team) +======= + @gitea_team = Gitea::Organization::Team::CreateService.call(user.gitea_token, org, team) +>>>>>>> 4a50873... [ADD]组织、组织团队 end def sync_team_gtid diff --git a/app/views/organizations/organization_users/_detail.json.jbuilder b/app/views/organizations/organization_users/_detail.json.jbuilder index 90426a61a..d4c21d5f5 100644 --- a/app/views/organizations/organization_users/_detail.json.jbuilder +++ b/app/views/organizations/organization_users/_detail.json.jbuilder @@ -4,4 +4,4 @@ json.user do end json.team_names org_user.teams.pluck(:name) -json.created_at org_user.created_at.strftime("%Y-%m-%d") \ No newline at end of file +json.created_at org_user.created_at.strftime("%Y-%m-%d") diff --git a/app/views/organizations/team_users/_detail.json.jbuilder b/app/views/organizations/team_users/_detail.json.jbuilder index 6bb6bf78a..040a3c172 100644 --- a/app/views/organizations/team_users/_detail.json.jbuilder +++ b/app/views/organizations/team_users/_detail.json.jbuilder @@ -2,4 +2,4 @@ json.id team_user.id json.user do json.partial! "organizations/user_detail", user: team_user.user end -json.created_at team_user.created_at.strftime("%Y-%m-%d") \ No newline at end of file +json.created_at team_user.created_at.strftime("%Y-%m-%d") From fef43caf4c4b1572a27886b73f01942a51a13ce1 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 19 Jan 2021 19:02:51 +0800 Subject: [PATCH 10/24] =?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/organizations/base_controller.rb | 16 ---------------- .../organizations/organizations_controller.rb | 1 - .../organizations/team_projects_controller.rb | 7 +++++++ app/models/organization_user.rb | 4 ---- .../organizations/teams/create_service.rb | 4 ---- 5 files changed, 7 insertions(+), 25 deletions(-) diff --git a/app/controllers/organizations/base_controller.rb b/app/controllers/organizations/base_controller.rb index 8bd4b2dd4..2e8ae0cf9 100644 --- a/app/controllers/organizations/base_controller.rb +++ b/app/controllers/organizations/base_controller.rb @@ -31,20 +31,4 @@ class Organizations::BaseController < ApplicationController def project_mark params[:repo_name] || params[:id] end - - def org_limited_condition - @organization.organization_extension.limited? && !current_user.logged? - end - - 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/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 2236d95bb..428948a73 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -31,7 +31,6 @@ 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? diff --git a/app/controllers/organizations/team_projects_controller.rb b/app/controllers/organizations/team_projects_controller.rb index f221c98db..1af476b83 100644 --- a/app/controllers/organizations/team_projects_controller.rb +++ b/app/controllers/organizations/team_projects_controller.rb @@ -11,7 +11,10 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def create +<<<<<<< HEAD tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project +======= +>>>>>>> ceda008... [ADD]组织项目相关 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) @@ -47,7 +50,11 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def load_operate_project +<<<<<<< HEAD @operate_project = Project.find_by(id: project_mark) || Project.find_by(identifier: project_mark) +======= + @operate_project = Project.find_by(name: params[:id]) || Project.find_by(identifier: params[:id]) +>>>>>>> ceda008... [ADD]组织项目相关 tip_exception("项目不存在") if @operate_project.nil? end diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index 1bf328f19..cf9e22371 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -31,8 +31,4 @@ class OrganizationUser < ApplicationRecord def teams organization.teams.joins(:team_users).where(team_users: {user_id: user_id}) end - - def teams - organization.teams.joins(:team_users).where(team_users: {user_id: user_id}) - end end diff --git a/app/services/organizations/teams/create_service.rb b/app/services/organizations/teams/create_service.rb index 867d41b12..81ad78772 100644 --- a/app/services/organizations/teams/create_service.rb +++ b/app/services/organizations/teams/create_service.rb @@ -65,11 +65,7 @@ class Organizations::Teams::CreateService < ApplicationService end def create_gitea_team -<<<<<<< HEAD @gitea_team = Gitea::Organization::Team::CreateService.call(org.gitea_token, org, team) -======= - @gitea_team = Gitea::Organization::Team::CreateService.call(user.gitea_token, org, team) ->>>>>>> 4a50873... [ADD]组织、组织团队 end def sync_team_gtid From dab57e9af30281e0018dc80a20fd064de052eae8 Mon Sep 17 00:00:00 2001 From: viletyy Date: Wed, 20 Jan 2021 18:48:28 +0800 Subject: [PATCH 11/24] =?UTF-8?q?[FIX]=E4=B8=80=E4=BA=9B=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=88=9B=E5=BB=BA=E6=9C=80=E5=A4=A7=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=95=B0=E9=87=8F=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/organizations/team_projects_controller.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/controllers/organizations/team_projects_controller.rb b/app/controllers/organizations/team_projects_controller.rb index 1af476b83..f221c98db 100644 --- a/app/controllers/organizations/team_projects_controller.rb +++ b/app/controllers/organizations/team_projects_controller.rb @@ -11,10 +11,7 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def create -<<<<<<< HEAD tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project -======= ->>>>>>> ceda008... [ADD]组织项目相关 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) @@ -50,11 +47,7 @@ class Organizations::TeamProjectsController < Organizations::BaseController end def load_operate_project -<<<<<<< HEAD @operate_project = Project.find_by(id: project_mark) || Project.find_by(identifier: project_mark) -======= - @operate_project = Project.find_by(name: params[:id]) || Project.find_by(identifier: params[:id]) ->>>>>>> ceda008... [ADD]组织项目相关 tip_exception("项目不存在") if @operate_project.nil? end From ce4c71c6a0f65b57b0dfcbef70e635a687f1e37f Mon Sep 17 00:00:00 2001 From: viletyy Date: Wed, 27 Jan 2021 17:34:34 +0800 Subject: [PATCH 12/24] =?UTF-8?q?[FIX]=E7=BB=84=E7=BB=87=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E4=B8=8D=E4=B8=8A=E4=BC=A0=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/organizations/organizations_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 428948a73..1e4bef746 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -57,7 +57,8 @@ class Organizations::OrganizationsController < Organizations::BaseController private def convert_image! - max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M + return unless params[:image].present? + max_size = EduSetting.get('upload_avatar_max_size').to_i || 2 * 1024 * 1024 # 2M if params[:image].class == ActionDispatch::Http::UploadedFile @image = params[:image] render_error('请上传文件') if @image.size.zero? From 3d495797c053bb71b79d2d22882e72e9bafe8787 Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 29 Jan 2021 15:27:11 +0800 Subject: [PATCH 13/24] [FIX]organization add created_at and total_count --- app/views/organizations/organizations/_detail.json.jbuilder | 3 ++- app/views/organizations/organizations/index.json.jbuilder | 1 + app/views/users/organizations/index.json.jbuilder | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/organizations/organizations/_detail.json.jbuilder b/app/views/organizations/organizations/_detail.json.jbuilder index d8dc17e81..0bf7c9896 100644 --- a/app/views/organizations/organizations/_detail.json.jbuilder +++ b/app/views/organizations/organizations/_detail.json.jbuilder @@ -8,4 +8,5 @@ json.visibility organization.visibility json.max_repo_creation organization.max_repo_creation json.num_projects organization.num_projects json.num_user organization.num_users -json.avatar_url url_to_avatar(organization) \ No newline at end of file +json.avatar_url url_to_avatar(organization) +json.created_at organization.created_on.strftime("%Y-%m-%d") \ No newline at end of file diff --git a/app/views/organizations/organizations/index.json.jbuilder b/app/views/organizations/organizations/index.json.jbuilder index b9066223f..33846d662 100644 --- a/app/views/organizations/organizations/index.json.jbuilder +++ b/app/views/organizations/organizations/index.json.jbuilder @@ -1,3 +1,4 @@ +json.total_count @organizations.total_count json.organizations @organizations do |organization| json.partial! "detail", organization: organization end diff --git a/app/views/users/organizations/index.json.jbuilder b/app/views/users/organizations/index.json.jbuilder index 3a3100b43..0a1950367 100644 --- a/app/views/users/organizations/index.json.jbuilder +++ b/app/views/users/organizations/index.json.jbuilder @@ -1,3 +1,4 @@ +json.total_count @organizations.total_count json.organizations @organizations do |organization| json.partial! "/organizations/organizations/detail", organization: organization end From c6269f44ee03c56e68f4ec0fff2d4e732454f27d Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 29 Jan 2021 15:47:43 +0800 Subject: [PATCH 14/24] [FIX]add user organization count --- app/controllers/users_controller.rb | 1 + app/models/owner.rb | 1 - app/views/users/show.json.jbuilder | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d5ca638a6..6c5c10fb3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -31,6 +31,7 @@ class UsersController < ApplicationController #用户的组织数量 # @user_composes_count = @user.composes.size @user_composes_count = 0 + @user_org_count = User.current.logged? ? @user.organizations.with_visibility(%w(common limited)).size + @user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).size : @user.organizations.with_visibility("common").size user_projects = User.current.logged? && (User.current.admin? || User.current.login == @user.login) ? @user.projects : @user.projects.visible @projects_common_count = user_projects.common.size @projects_mirrior_count = user_projects.mirror.size diff --git a/app/models/owner.rb b/app/models/owner.rb index e058ab564..d4194c32c 100644 --- a/app/models/owner.rb +++ b/app/models/owner.rb @@ -61,7 +61,6 @@ class Owner < ApplicationRecord self.table_name = "users" - include ProjectOperable include ProjectAbility has_many :projects, foreign_key: :user_id, dependent: :destroy diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder index 9b4956197..54f85c5c2 100644 --- a/app/views/users/show.json.jbuilder +++ b/app/views/users/show.json.jbuilder @@ -12,6 +12,7 @@ json.watched_count @user.fan_count #粉丝 json.watching_count @user.follow_count #关注数 json.undo_events @undo_events json.user_composes_count @user_composes_count +json.user_org_count @user_org_count json.common_projects_count @projects_common_count json.mirror_projects_count @projects_mirrior_count json.sync_mirror_projects_count @projects_sync_mirrior_count \ No newline at end of file From 152e301bf3b5cc862a736460dd48459003ef2342 Mon Sep 17 00:00:00 2001 From: viletyy Date: Mon, 1 Feb 2021 14:50:56 +0800 Subject: [PATCH 15/24] [ADD]search is_member is_admin --- .../organizations/organization_users_controller.rb | 2 ++ .../organizations/organizations_controller.rb | 2 ++ .../organizations/projects_controller.rb | 13 +++++++++++++ .../organizations/team_users_controller.rb | 3 +++ app/controllers/organizations/teams_controller.rb | 2 ++ app/models/organization.rb | 4 ++++ app/models/team.rb | 4 ++++ .../organizations/organizations/show.json.jbuilder | 4 +++- .../organizations/projects/search.json.jbuilder | 9 +++++++++ .../team_projects/_detail.json.jbuilder | 1 + app/views/organizations/teams/show.json.jbuilder | 4 +++- config/routes.rb | 6 +++++- 12 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 app/views/organizations/projects/search.json.jbuilder diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 6c3afa963..9bb00467a 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -4,6 +4,8 @@ class Organizations::OrganizationUsersController < Organizations::BaseController def index @organization_users = @organization.organization_users.includes(:user) + search = params[:search].to_s.downcase + @organization_users = @organization_users.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? @organization_users = kaminari_paginate(@organization_users) end diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 1e4bef746..35cc1d404 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -18,6 +18,8 @@ class Organizations::OrganizationsController < Organizations::BaseController end def show + @is_admin = can_edit_org? + @is_member = @organization.is_member?(current_user.id) end def create diff --git a/app/controllers/organizations/projects_controller.rb b/app/controllers/organizations/projects_controller.rb index eb6371f72..aabb781b4 100644 --- a/app/controllers/organizations/projects_controller.rb +++ b/app/controllers/organizations/projects_controller.rb @@ -14,6 +14,19 @@ class Organizations::ProjectsController < Organizations::BaseController @projects = paginate(@projects) end + def search + tip_exception("请输入搜索关键词") if params[:search].nil? + 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 + @projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}") + end + private def load_organization diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb index 1529aa360..1b225e5c2 100644 --- a/app/controllers/organizations/team_users_controller.rb +++ b/app/controllers/organizations/team_users_controller.rb @@ -7,6 +7,9 @@ class Organizations::TeamUsersController < Organizations::BaseController def index @team_users = @team.team_users + search = params[:search].to_s.downcase + @team_users = @team_users.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? + @team_users = kaminari_paginate(@team_users) end diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 5e6185d19..939334c71 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -14,6 +14,8 @@ class Organizations::TeamsController < Organizations::BaseController end def show + @is_admin = can_edit_org? + @is_member = @team.is_member?(current_user.id) end def create diff --git a/app/models/organization.rb b/app/models/organization.rb index fb8d94c40..8bda95aff 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -78,6 +78,10 @@ class Organization < Owner self.create!(login: name, gitea_token: gitea_token) end + def is_member?(user_id) + organization_users.where(user_id: user_id).present? + end + def is_owner?(user_id) team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(owner)}).present? end diff --git a/app/models/team.rb b/app/models/team.rb index 382019f77..3e1de9ad8 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -47,4 +47,8 @@ class Team < ApplicationRecord end end + def is_member?(user_id) + team_users.where(user_id: user_id).present? + end + end diff --git a/app/views/organizations/organizations/show.json.jbuilder b/app/views/organizations/organizations/show.json.jbuilder index 55de73daf..2fd88b7b0 100644 --- a/app/views/organizations/organizations/show.json.jbuilder +++ b/app/views/organizations/organizations/show.json.jbuilder @@ -1 +1,3 @@ -json.partial! "detail", organization: @organization \ No newline at end of file +json.partial! "detail", organization: @organization +json.is_admin @is_admin +json.is_member @is_member \ No newline at end of file diff --git a/app/views/organizations/projects/search.json.jbuilder b/app/views/organizations/projects/search.json.jbuilder new file mode 100644 index 000000000..cf2b86019 --- /dev/null +++ b/app/views/organizations/projects/search.json.jbuilder @@ -0,0 +1,9 @@ +json.total_count @projects.size +json.projects @projects.each do |project| + json.(project, :id, :name, :identifier, :description, :forked_count, :praises_count, :forked_from_project_id) + json.mirror_url project.repository&.mirror_url + json.type project.numerical_for_project_type + 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/organizations/team_projects/_detail.json.jbuilder b/app/views/organizations/team_projects/_detail.json.jbuilder index d65021086..9af32d1df 100644 --- a/app/views/organizations/team_projects/_detail.json.jbuilder +++ b/app/views/organizations/team_projects/_detail.json.jbuilder @@ -1,6 +1,7 @@ json.id team_project.id json.project do json.owner_name team_project&.project&.owner&.login + json.owner_image_url url_to_avatar(team_project&.project&.owner) json.name team_project&.project&.name json.identifier team_project&.project&.identifier end \ No newline at end of file diff --git a/app/views/organizations/teams/show.json.jbuilder b/app/views/organizations/teams/show.json.jbuilder index 25f229ce8..d0290897a 100644 --- a/app/views/organizations/teams/show.json.jbuilder +++ b/app/views/organizations/teams/show.json.jbuilder @@ -1 +1,3 @@ -json.partial! "detail", team: @team, organization: @organization \ No newline at end of file +json.partial! "detail", team: @team, organization: @organization +json.is_admin @is_admin +json.is_member @is_member \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 20d5fbe68..1a1fffd22 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -120,7 +120,11 @@ Rails.application.routes.draw do end resources :team_projects, only: [:index, :create, :destroy] do ;end end - resources :projects, only: [:index] + resources :projects, only: [:index] do + collection do + get :search + end + end end end From 1e70764d6358c21301c7197d6b9a3f6138e9b521 Mon Sep 17 00:00:00 2001 From: viletyy Date: Mon, 1 Feb 2021 15:35:35 +0800 Subject: [PATCH 16/24] [FIX]teams add user info --- app/controllers/organizations/teams_controller.rb | 2 ++ app/views/organizations/teams/_detail.json.jbuilder | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 939334c71..d3437d23c 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -9,6 +9,8 @@ class Organizations::TeamsController < Organizations::BaseController else @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) end + @is_admin = can_edit_org? + @teams = @teams.includes(:team_units, :team_users) @teams = kaminari_paginate(@teams) end diff --git a/app/views/organizations/teams/_detail.json.jbuilder b/app/views/organizations/teams/_detail.json.jbuilder index 36011a98f..4f3588cb9 100644 --- a/app/views/organizations/teams/_detail.json.jbuilder +++ b/app/views/organizations/teams/_detail.json.jbuilder @@ -7,3 +7,8 @@ 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) +json.users team.team_users.each do |user| + json.partial! "organizations/user_detail", user: user&.user +end +json.is_admin @is_admin +json.is_member team.is_member?(current_user.id) From ddaca5bafc439d5c70b99066c07e2bcf5af23507 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 2 Feb 2021 14:21:02 +0800 Subject: [PATCH 17/24] [ADD]organization add num_teams --- app/models/organization.rb | 2 +- app/models/organization_extension.rb | 2 + app/models/project.rb | 139 +++++++++--------- app/models/team.rb | 1 + .../organizations/_detail.json.jbuilder | 1 + ...1_add_columns_to_organization_extension.rb | 7 + 6 files changed, 82 insertions(+), 70 deletions(-) diff --git a/app/models/organization.rb b/app/models/organization.rb index 8bda95aff..06338bfd5 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -70,7 +70,7 @@ class Organization < Owner validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false delegate :description, :website, :location, :repo_admin_change_team_access, - :visibility, :max_repo_creation, :num_projects, :num_users, to: :organization_extension, allow_nil: true + :visibility, :max_repo_creation, :num_projects, :num_users, :num_teams, to: :organization_extension, allow_nil: true scope :with_visibility, ->(visibility) { joins(:organization_extension).where(organization_extensions: {visibility: visibility}) if visibility.present? } diff --git a/app/models/organization_extension.rb b/app/models/organization_extension.rb index 16797f716..8b9946cd7 100644 --- a/app/models/organization_extension.rb +++ b/app/models/organization_extension.rb @@ -14,6 +14,7 @@ # updated_at :datetime not null # num_projects :integer default("0") # num_users :integer default("0") +# num_teams :integer default("0") # # Indexes # @@ -25,6 +26,7 @@ class OrganizationExtension < ApplicationRecord belongs_to :organization has_many :organization_users, foreign_key: :organization_id, primary_key: :organization_id has_many :projects, foreign_key: :user_id, primary_key: :organization_id + has_many :teams, foreign_key: :organization_id, primary_key: :organization_id enum visibility: {common: 0, limited: 1, privacy: 2} diff --git a/app/models/project.rb b/app/models/project.rb index a91cf891d..feb0d3067 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,72 +1,73 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) default(""), not null -# description :text(4294967295) -# homepage :string(255) default("") -# is_public :boolean default("1"), not null -# parent_id :integer -# created_on :datetime -# updated_on :datetime -# identifier :string(255) -# status :integer default("1"), not null -# lft :integer -# rgt :integer -# inherit_members :boolean default("0"), not null -# project_type :integer default("0") -# hidden_repo :boolean default("0"), not null -# attachmenttype :integer default("1") -# user_id :integer -# dts_test :integer default("0") -# enterprise_name :string(255) -# organization_id :integer -# project_new_type :integer -# gpid :integer -# forked_from_project_id :integer -# forked_count :integer default("0") -# publish_resource :integer default("0") -# visits :integer default("0") -# hot :integer default("0") -# invite_code :string(255) -# qrcode :string(255) -# qrcode_expiretime :integer default("0") -# script :text(65535) -# training_status :integer default("0") -# rep_identifier :string(255) -# project_category_id :integer -# project_language_id :integer -# license_id :integer -# ignore_id :integer -# praises_count :integer default("0") -# watchers_count :integer default("0") -# issues_count :integer default("0") -# pull_requests_count :integer default("0") -# language :string(255) -# versions_count :integer default("0") -# issue_tags_count :integer default("0") -# closed_issues_count :integer default("0") -# open_devops :boolean default("0") -# gitea_webhook_id :integer -# open_devops_count :integer default("0") -# recommend :boolean default("0") -# platform :integer default("0") -# -# Indexes -# -# index_projects_on_forked_from_project_id (forked_from_project_id) -# index_projects_on_identifier (identifier) -# index_projects_on_is_public (is_public) -# index_projects_on_lft (lft) -# index_projects_on_name (name) -# index_projects_on_platform (platform) -# index_projects_on_project_type (project_type) -# index_projects_on_recommend (recommend) -# index_projects_on_rgt (rgt) -# index_projects_on_status (status) -# index_projects_on_updated_on (updated_on) -# +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) default(""), not null +# description :text(4294967295) +# homepage :string(255) default("") +# is_public :boolean default("1"), not null +# parent_id :integer +# created_on :datetime +# updated_on :datetime +# identifier :string(255) +# status :integer default("1"), not null +# lft :integer +# rgt :integer +# inherit_members :boolean default("0"), not null +# project_type :integer default("0") +# hidden_repo :boolean default("0"), not null +# attachmenttype :integer default("1") +# user_id :integer +# dts_test :integer default("0") +# enterprise_name :string(255) +# organization_id :integer +# project_new_type :integer +# gpid :integer +# forked_from_project_id :integer +# forked_count :integer default("0") +# publish_resource :integer default("0") +# visits :integer default("0") +# hot :integer default("0") +# invite_code :string(255) +# qrcode :string(255) +# qrcode_expiretime :integer default("0") +# script :text(65535) +# training_status :integer default("0") +# rep_identifier :string(255) +# project_category_id :integer +# project_language_id :integer +# license_id :integer +# ignore_id :integer +# praises_count :integer default("0") +# watchers_count :integer default("0") +# issues_count :integer default("0") +# pull_requests_count :integer default("0") +# language :string(255) +# versions_count :integer default("0") +# issue_tags_count :integer default("0") +# closed_issues_count :integer default("0") +# open_devops :boolean default("0") +# gitea_webhook_id :integer +# open_devops_count :integer default("0") +# recommend :boolean default("0") +# platform :integer default("0") +# +# Indexes +# +# index_projects_on_forked_from_project_id (forked_from_project_id) +# index_projects_on_identifier (identifier) +# index_projects_on_is_public (is_public) +# index_projects_on_lft (lft) +# index_projects_on_name (name) +# index_projects_on_platform (platform) +# index_projects_on_project_type (project_type) +# index_projects_on_recommend (recommend) +# index_projects_on_rgt (rgt) +# index_projects_on_status (status) +# index_projects_on_updated_on (updated_on) +# + class Project < ApplicationRecord include Matchable diff --git a/app/models/team.rb b/app/models/team.rb index 3e1de9ad8..82a3e88c1 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -23,6 +23,7 @@ class Team < ApplicationRecord belongs_to :organization + belongs_to :organization_extension, foreign_key: :organization_id, primary_key: :organization_id, counter_cache: :num_teams has_many :team_projects, dependent: :destroy has_many :team_units, dependent: :destroy has_many :team_users, dependent: :destroy diff --git a/app/views/organizations/organizations/_detail.json.jbuilder b/app/views/organizations/organizations/_detail.json.jbuilder index 0bf7c9896..99932b20d 100644 --- a/app/views/organizations/organizations/_detail.json.jbuilder +++ b/app/views/organizations/organizations/_detail.json.jbuilder @@ -8,5 +8,6 @@ json.visibility organization.visibility json.max_repo_creation organization.max_repo_creation json.num_projects organization.num_projects json.num_user organization.num_users +json.num_teams organization.num_teams json.avatar_url url_to_avatar(organization) json.created_at organization.created_on.strftime("%Y-%m-%d") \ No newline at end of file diff --git a/db/migrate/20210120081821_add_columns_to_organization_extension.rb b/db/migrate/20210120081821_add_columns_to_organization_extension.rb index 96089c9ce..4bcb4d9f3 100644 --- a/db/migrate/20210120081821_add_columns_to_organization_extension.rb +++ b/db/migrate/20210120081821_add_columns_to_organization_extension.rb @@ -2,5 +2,12 @@ class AddColumnsToOrganizationExtension < ActiveRecord::Migration[5.2] def change add_column :organization_extensions, :num_projects, :integer, default: 0 add_column :organization_extensions, :num_users, :integer, default: 0 + add_column :organization_extensions, :num_teams, :integer, default: 0 + + OrganizationExtension.find_each do |e| + OrganizationExtension.reset_counters(e.id, :organization_users) + OrganizationExtension.reset_counters(e.id, :projects) + OrganizationExtension.reset_counters(e.id, :teams) + end end end From 629f3fbbe1b41fd573c3ab2f1cb198b38c8738c0 Mon Sep 17 00:00:00 2001 From: viletyy Date: Tue, 2 Feb 2021 16:06:24 +0800 Subject: [PATCH 18/24] [FIX]little vliad about team_user --- .../organizations/organization_users_controller.rb | 4 ++-- app/controllers/organizations/team_users_controller.rb | 4 ++-- app/controllers/organizations/teams_controller.rb | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 9bb00467a..52e5866d8 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -11,7 +11,7 @@ class Organizations::OrganizationUsersController < Organizations::BaseController end def destroy - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user.id) ActiveRecord::Base.transaction do @organization_user.destroy! TeamUser.where(organization_id: @organization.id, user_id: @operate_user.id).map{|u| u.destroy!} @@ -26,7 +26,7 @@ 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) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(current_user.id) ActiveRecord::Base.transaction do @organization_user.destroy! TeamUser.where(organization_id: @organization.id, user_id: current_user.id).map{|u| u.destroy!} diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb index 1b225e5c2..7065ef6a3 100644 --- a/app/controllers/organizations/team_users_controller.rb +++ b/app/controllers/organizations/team_users_controller.rb @@ -25,7 +25,7 @@ class Organizations::TeamUsersController < Organizations::BaseController end def destroy - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login) @@ -39,7 +39,7 @@ 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 @organization.is_owner_team_last_one?(current_user) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(current_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, current_user.login) diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index d3437d23c..26c56f39f 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -4,7 +4,7 @@ class Organizations::TeamsController < Organizations::BaseController before_action :check_user_can_edit_org, only: [:create, :update, :destroy] def index - if @organization.is_owner?(current_user) + if @organization.is_owner?(current_user) || current_user.admin? @teams = @organization.teams else @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) @@ -35,6 +35,7 @@ class Organizations::TeamsController < Organizations::BaseController end def destroy + tip_exception("组织团队不允许被删除") if @team.owner? ActiveRecord::Base.transaction do Gitea::Organization::Team::DeleteService.call(@organization.gitea_token, @team.gtid) @team.destroy! From 4f6f257b378b91d96bfb468348096df92f6f630c Mon Sep 17 00:00:00 2001 From: viletyy Date: Wed, 3 Feb 2021 18:29:14 +0800 Subject: [PATCH 19/24] [FIX]concat change to concat_ws, org render 403, normal team leave --- .../organization_users_controller.rb | 6 +++--- .../organizations/organizations_controller.rb | 4 ++-- .../organizations/projects_controller.rb | 4 ++-- .../organizations/team_projects_controller.rb | 8 ++++---- .../organizations/team_users_controller.rb | 16 ++++++++-------- .../organizations/teams_controller.rb | 8 ++++---- .../organizations/_detail.json.jbuilder | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 52e5866d8..0b2d9393c 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -5,7 +5,7 @@ class Organizations::OrganizationUsersController < Organizations::BaseController def index @organization_users = @organization.organization_users.includes(:user) search = params[:search].to_s.downcase - @organization_users = @organization_users.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? + @organization_users = @organization_users.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? @organization_users = kaminari_paginate(@organization_users) end @@ -41,8 +41,8 @@ class Organizations::OrganizationUsersController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition end def load_operate_user diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 35cc1d404..8346886e9 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -90,8 +90,8 @@ class Organizations::OrganizationsController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition end def sort_by diff --git a/app/controllers/organizations/projects_controller.rb b/app/controllers/organizations/projects_controller.rb index aabb781b4..cc275b090 100644 --- a/app/controllers/organizations/projects_controller.rb +++ b/app/controllers/organizations/projects_controller.rb @@ -31,8 +31,8 @@ class Organizations::ProjectsController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition end def sort diff --git a/app/controllers/organizations/team_projects_controller.rb b/app/controllers/organizations/team_projects_controller.rb index f221c98db..2badca177 100644 --- a/app/controllers/organizations/team_projects_controller.rb +++ b/app/controllers/organizations/team_projects_controller.rb @@ -36,14 +36,14 @@ class Organizations::TeamProjectsController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") 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 + return render_not_found("组织团队不存在") if @team.nil? + return render_forbidden("没有查看组织团队的权限") if team_not_found_condition end def load_operate_project diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb index 7065ef6a3..a8e834423 100644 --- a/app/controllers/organizations/team_users_controller.rb +++ b/app/controllers/organizations/team_users_controller.rb @@ -5,10 +5,10 @@ class Organizations::TeamUsersController < Organizations::BaseController before_action :check_user_can_edit_org, only: [:create, :destroy] def index - @team_users = @team.team_users + @team_users = @team.team_users.includes(:user) search = params[:search].to_s.downcase - @team_users = @team_users.joins(:user).where("LOWER(concat(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? + @team_users = @team_users.joins(:user).where("LOWER(CONCAT_WS(users.lastname, users.firstname, users.login, users.mail, users.nickname)) LIKE ?", "%#{search.split(" ").join('|')}%") if search.present? @team_users = kaminari_paginate(@team_users) end @@ -25,7 +25,7 @@ class Organizations::TeamUsersController < Organizations::BaseController end def destroy - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user.id) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @organization.is_owner_team_last_one?(@operate_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login) @@ -39,7 +39,7 @@ 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 @organization.is_owner_team_last_one?(current_user.id) + tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @organization.is_owner_team_last_one?(current_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, current_user.login) @@ -53,14 +53,14 @@ class Organizations::TeamUsersController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") 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 + return render_not_found("组织团队不存在") if @team.nil? + return render_forbidden("没有查看组织团队的权限") if team_not_found_condition end def load_operate_user diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 26c56f39f..577b3121a 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -53,13 +53,13 @@ class Organizations::TeamsController < Organizations::BaseController 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 + return render_not_found("组织不存在") if @organization.nil? + return render_forbidden("没有查看组织的权限") 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 + return render_not_found("组织团队不存在") if @team.nil? + return render_forbidden("没有查看组织团队的权限") if team_not_found_condition end end \ No newline at end of file diff --git a/app/views/organizations/organizations/_detail.json.jbuilder b/app/views/organizations/organizations/_detail.json.jbuilder index 99932b20d..e7aafd4e9 100644 --- a/app/views/organizations/organizations/_detail.json.jbuilder +++ b/app/views/organizations/organizations/_detail.json.jbuilder @@ -7,7 +7,7 @@ json.repo_admin_change_team_access organization.repo_admin_change_team_access json.visibility organization.visibility json.max_repo_creation organization.max_repo_creation json.num_projects organization.num_projects -json.num_user organization.num_users +json.num_users organization.num_users json.num_teams organization.num_teams json.avatar_url url_to_avatar(organization) json.created_at organization.created_on.strftime("%Y-%m-%d") \ No newline at end of file From 54204d4db8ceb90ff2a0611710426519817eb588 Mon Sep 17 00:00:00 2001 From: viletyy Date: Thu, 4 Feb 2021 17:03:56 +0800 Subject: [PATCH 20/24] [ADD]org team search, project teams add\remove, org can create field [FIX] --- .../organizations/organizations_controller.rb | 7 +- .../organizations/teams_controller.rb | 12 ++ app/controllers/projects/teams_controller.rb | 39 ++++- app/models/concerns/project_operable.rb | 6 +- app/models/organization.rb | 4 + app/models/project.rb | 141 +++++++++--------- app/models/user.rb | 4 +- app/services/repositories/create_service.rb | 6 + .../organizations/show.json.jbuilder | 1 + .../organizations/teams/search.json.jbuilder | 4 + app/views/projects/teams/index.json.jbuilder | 1 + config/routes.rb | 5 +- 12 files changed, 150 insertions(+), 80 deletions(-) create mode 100644 app/views/organizations/teams/search.json.jbuilder diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 8346886e9..e03ddf121 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -18,6 +18,7 @@ class Organizations::OrganizationsController < Organizations::BaseController end def show + @can_create_project = @organization.can_create_project?(current_user.id) @is_admin = can_edit_org? @is_member = @organization.is_member?(current_user.id) end @@ -60,15 +61,15 @@ class Organizations::OrganizationsController < Organizations::BaseController private def convert_image! return unless params[:image].present? - max_size = EduSetting.get('upload_avatar_max_size').to_i || 2 * 1024 * 1024 # 2M + max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M if params[:image].class == ActionDispatch::Http::UploadedFile @image = params[:image] render_error('请上传文件') if @image.size.zero? - render_error('文件大小超过限制') if @image.size > max_size + render_error('文件大小超过限制') if @image.size > max_size.to_i else image = params[:image].to_s.strip return render_error('请上传正确的图片') if image.blank? - @image = Util.convert_base64_image(image, max_size: max_size) + @image = Util.convert_base64_image(image, max_size: max_size.to_i) end rescue Base64ImageConverter::Error => ex render_error(ex.message) diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 577b3121a..47e95559f 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -15,6 +15,18 @@ class Organizations::TeamsController < Organizations::BaseController @teams = kaminari_paginate(@teams) end + def search + tip_exception("请输入搜索关键词") if params[:search].nil? + if @organization.is_owner?(current_user) || current_user.admin? + @teams = @organization.teams + else + @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) + end + @is_admin = can_edit_org? + @teams = @teams.ransack(name_cont: params[:search]).result if params[:search].present? + @teams = @teams.includes(:team_units, :team_users) + end + def show @is_admin = can_edit_org? @is_member = @team.is_member?(current_user.id) diff --git a/app/controllers/projects/teams_controller.rb b/app/controllers/projects/teams_controller.rb index d5b7ea1e8..b6ea32185 100644 --- a/app/controllers/projects/teams_controller.rb +++ b/app/controllers/projects/teams_controller.rb @@ -1,10 +1,47 @@ class Projects::TeamsController < Projects::BaseController + before_action :load_operate_team, only: [:create, :destroy] + before_action :load_team_project, only: :destroy + def index if @project.owner.is_a?(Organization) - @teams = @project.owner.teams + @teams = Team.joins(:team_projects).where(team_projects: {project_id: @project.id}) else @teams = Team.none end @teams = paginate(@teams) end + + def create + ActiveRecord::Base.transaction do + @team_project = TeamProject.build(@owner.id, @operate_team.id, @project.id) + Gitea::Organization::TeamProject::CreateService.call(@owner.gitea_token, @operate_team.gtid, @owner.login, @project.identifier) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + ActiveRecord::Base.transaction do + @team_project.destroy! + Gitea::Organization::TeamProject::DeleteService.call(@owner.gitea_token, @operate_team.gtid, @owner.login, @project.identifier) + render_ok + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + private + def load_operate_team + @operate_team = Team.find_by(id: params[:team_id]) || Team.find_by(id: params[:id]) + tip_exception("项目不存在") if @operate_team.nil? + tip_exception("该组织团队拥有组织所有项目,无法进行操作") if @operate_team.includes_all_project + end + + def load_team_project + @team_project = TeamProject.find_by(organization_id: @owner.id, team_id: @operate_team.id, project_id: @project.id) + tip_exception("组织团队项目不存在") if @team_project.nil? + end end \ No newline at end of file diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb index a45049882..5e8bf43d9 100644 --- a/app/models/concerns/project_operable.rb +++ b/app/models/concerns/project_operable.rb @@ -13,7 +13,7 @@ module ProjectOperable def add_member!(user_id, role_name='Developer') member = members.create!(user_id: user_id) - set_developer_role(member) + set_developer_role(member, role_name) end def remove_member!(user_id) @@ -84,8 +84,8 @@ module ProjectOperable end end - def set_developer_role(member) - role = Role.find_by_name 'Developer' + def set_developer_role(member, role_name) + role = Role.find_by(name: role_name) member.member_roles.create!(role: role) end diff --git a/app/models/organization.rb b/app/models/organization.rb index 06338bfd5..5c66c5ff4 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -78,6 +78,10 @@ class Organization < Owner self.create!(login: name, gitea_token: gitea_token) end + def can_create_project?(user_id) + team_users.joins(:team).where(user_id: user_id, teams: {can_create_org_project: true}).present? + end + def is_member?(user_id) organization_users.where(user_id: user_id).present? end diff --git a/app/models/project.rb b/app/models/project.rb index feb0d3067..f82674dbc 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,73 +1,73 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) default(""), not null -# description :text(4294967295) -# homepage :string(255) default("") -# is_public :boolean default("1"), not null -# parent_id :integer -# created_on :datetime -# updated_on :datetime -# identifier :string(255) -# status :integer default("1"), not null -# lft :integer -# rgt :integer -# inherit_members :boolean default("0"), not null -# project_type :integer default("0") -# hidden_repo :boolean default("0"), not null -# attachmenttype :integer default("1") -# user_id :integer -# dts_test :integer default("0") -# enterprise_name :string(255) -# organization_id :integer -# project_new_type :integer -# gpid :integer -# forked_from_project_id :integer -# forked_count :integer default("0") -# publish_resource :integer default("0") -# visits :integer default("0") -# hot :integer default("0") -# invite_code :string(255) -# qrcode :string(255) -# qrcode_expiretime :integer default("0") -# script :text(65535) -# training_status :integer default("0") -# rep_identifier :string(255) -# project_category_id :integer -# project_language_id :integer -# license_id :integer -# ignore_id :integer -# praises_count :integer default("0") -# watchers_count :integer default("0") -# issues_count :integer default("0") -# pull_requests_count :integer default("0") -# language :string(255) -# versions_count :integer default("0") -# issue_tags_count :integer default("0") -# closed_issues_count :integer default("0") -# open_devops :boolean default("0") -# gitea_webhook_id :integer -# open_devops_count :integer default("0") -# recommend :boolean default("0") -# platform :integer default("0") -# -# Indexes -# -# index_projects_on_forked_from_project_id (forked_from_project_id) -# index_projects_on_identifier (identifier) -# index_projects_on_is_public (is_public) -# index_projects_on_lft (lft) -# index_projects_on_name (name) -# index_projects_on_platform (platform) -# index_projects_on_project_type (project_type) -# index_projects_on_recommend (recommend) -# index_projects_on_rgt (rgt) -# index_projects_on_status (status) -# index_projects_on_updated_on (updated_on) -# - +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) default(""), not null +# description :text(4294967295) +# homepage :string(255) default("") +# is_public :boolean default("1"), not null +# parent_id :integer +# created_on :datetime +# updated_on :datetime +# identifier :string(255) +# status :integer default("1"), not null +# lft :integer +# rgt :integer +# inherit_members :boolean default("0"), not null +# project_type :integer default("0") +# hidden_repo :boolean default("0"), not null +# attachmenttype :integer default("1") +# user_id :integer +# dts_test :integer default("0") +# enterprise_name :string(255) +# organization_id :integer +# project_new_type :integer +# gpid :integer +# forked_from_project_id :integer +# forked_count :integer default("0") +# publish_resource :integer default("0") +# visits :integer default("0") +# hot :integer default("0") +# invite_code :string(255) +# qrcode :string(255) +# qrcode_expiretime :integer default("0") +# script :text(65535) +# training_status :integer default("0") +# rep_identifier :string(255) +# project_category_id :integer +# project_language_id :integer +# license_id :integer +# ignore_id :integer +# praises_count :integer default("0") +# watchers_count :integer default("0") +# issues_count :integer default("0") +# pull_requests_count :integer default("0") +# language :string(255) +# versions_count :integer default("0") +# issue_tags_count :integer default("0") +# closed_issues_count :integer default("0") +# open_devops :boolean default("0") +# gitea_webhook_id :integer +# open_devops_count :integer default("0") +# recommend :boolean default("0") +# platform :integer default("0") +# +# Indexes +# +# index_projects_on_forked_from_project_id (forked_from_project_id) +# index_projects_on_identifier (identifier) +# index_projects_on_is_public (is_public) +# index_projects_on_lft (lft) +# index_projects_on_name (name) +# index_projects_on_platform (platform) +# index_projects_on_project_type (project_type) +# index_projects_on_recommend (recommend) +# index_projects_on_rgt (rgt) +# index_projects_on_status (status) +# index_projects_on_updated_on (updated_on) +# + class Project < ApplicationRecord include Matchable @@ -108,6 +108,7 @@ class Project < ApplicationRecord has_many :praise_treads, as: :praise_tread_object, dependent: :destroy has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position" has_one :project_detail, dependent: :destroy + has_many :team_projects, dependent: :destroy after_save :check_project_members scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)} diff --git a/app/models/user.rb b/app/models/user.rb index 250a9b8b2..1cb6670c6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -135,8 +135,8 @@ class User < Owner has_many :attachments,foreign_key: :author_id, :dependent => :destroy # 关注 - has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注 - has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户 + # 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/services/repositories/create_service.rb b/app/services/repositories/create_service.rb index 9b89490fb..9da2fe94f 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -13,6 +13,7 @@ class Repositories::CreateService < ApplicationService ActiveRecord::Base.transaction do if repository.save! create_gitea_repository + create_manager_member sync_project sync_repository # if project.project_type == "common" @@ -51,6 +52,11 @@ class Repositories::CreateService < ApplicationService end end + def create_manager_member + return if project.owner.is_owner?(user.id) + project.add_member!(user.id, "Manager") + end + def sync_project if gitea_repository project.update_columns( diff --git a/app/views/organizations/organizations/show.json.jbuilder b/app/views/organizations/organizations/show.json.jbuilder index 2fd88b7b0..ab803751c 100644 --- a/app/views/organizations/organizations/show.json.jbuilder +++ b/app/views/organizations/organizations/show.json.jbuilder @@ -1,3 +1,4 @@ json.partial! "detail", organization: @organization +json.can_create_project @can_create_project json.is_admin @is_admin json.is_member @is_member \ No newline at end of file diff --git a/app/views/organizations/teams/search.json.jbuilder b/app/views/organizations/teams/search.json.jbuilder new file mode 100644 index 000000000..c07b8b870 --- /dev/null +++ b/app/views/organizations/teams/search.json.jbuilder @@ -0,0 +1,4 @@ +json.total_count @teams.size +json.teams @teams do |team| + json.partial! "detail", team: team, organization: @organization +end diff --git a/app/views/projects/teams/index.json.jbuilder b/app/views/projects/teams/index.json.jbuilder index f6f7572b8..0a48e884d 100644 --- a/app/views/projects/teams/index.json.jbuilder +++ b/app/views/projects/teams/index.json.jbuilder @@ -1,4 +1,5 @@ json.total_count @teams.total_count json.teams @teams.each do |team| json.(team, :id, :name, :authorize) + json.can_remove !team.includes_all_project && team&.organization&.repo_admin_change_team_access end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1a1fffd22..2d8861416 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -113,6 +113,9 @@ Rails.application.routes.draw do end end resources :teams, except: [:edit, :new] do + collection do + get :search + end resources :team_users, only: [:index, :create, :destroy] do collection do delete :quit @@ -519,7 +522,7 @@ Rails.application.routes.draw do end scope module: :projects do - resources :teams, only: [:index] + resources :teams, only: [:index, :create, :destroy] scope do get( '/blob/*id/diff', From 55528950f1153174b643f03d98c0600d4e18022b Mon Sep 17 00:00:00 2001 From: viletyy Date: Thu, 4 Feb 2021 17:30:49 +0800 Subject: [PATCH 21/24] [FIX]owner text --- .../organizations/organization_users_controller.rb | 4 ++-- app/controllers/organizations/team_users_controller.rb | 4 ++-- app/services/organizations/create_service.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/organizations/organization_users_controller.rb b/app/controllers/organizations/organization_users_controller.rb index 0b2d9393c..8a7755a1b 100644 --- a/app/controllers/organizations/organization_users_controller.rb +++ b/app/controllers/organizations/organization_users_controller.rb @@ -11,7 +11,7 @@ class Organizations::OrganizationUsersController < Organizations::BaseController end def destroy - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user.id) + tip_exception("您不能从所有者团队中删除最后一个用户") if @organization.is_owner_team_last_one?(@operate_user.id) ActiveRecord::Base.transaction do @organization_user.destroy! TeamUser.where(organization_id: @organization.id, user_id: @operate_user.id).map{|u| u.destroy!} @@ -26,7 +26,7 @@ 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.id) + tip_exception("您不能从所有者团队中删除最后一个用户") if @organization.is_owner_team_last_one?(current_user.id) ActiveRecord::Base.transaction do @organization_user.destroy! TeamUser.where(organization_id: @organization.id, user_id: current_user.id).map{|u| u.destroy!} diff --git a/app/controllers/organizations/team_users_controller.rb b/app/controllers/organizations/team_users_controller.rb index a8e834423..d8694a6c5 100644 --- a/app/controllers/organizations/team_users_controller.rb +++ b/app/controllers/organizations/team_users_controller.rb @@ -25,7 +25,7 @@ class Organizations::TeamUsersController < Organizations::BaseController end def destroy - tip_exception("您不能从 Owner 团队中删除最后一个用户") if @team.owner? && @organization.is_owner_team_last_one?(@operate_user.id) + tip_exception("您不能从所有者团队中删除最后一个用户") if @team.owner? && @organization.is_owner_team_last_one?(@operate_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login) @@ -39,7 +39,7 @@ 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? && @organization.is_owner_team_last_one?(current_user.id) + tip_exception("您不能从所有者团队中删除最后一个用户") if @team.owner? && @organization.is_owner_team_last_one?(current_user.id) ActiveRecord::Base.transaction do @team_user.destroy! Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, current_user.login) diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index c2ca0f431..218fa2115 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -54,7 +54,7 @@ class Organizations::CreateService < ApplicationService end def create_owner_info - @owner_team = Team.build(organization.id, "Owner", "", 4, true, true) + @owner_team = Team.build(organization.id, "Owners", "", 4, true, true) TeamUnit.unit_types.keys.each do |u_type| TeamUnit.build(organization.id, owner_team.id, u_type) end From ec1acde99ae5eb721288674eea8e55c15df5d883 Mon Sep 17 00:00:00 2001 From: viletyy Date: Fri, 5 Feb 2021 15:06:13 +0800 Subject: [PATCH 22/24] [FIX]show teams, org name valid message --- app/controllers/organizations/teams_controller.rb | 8 ++++---- app/models/organization.rb | 4 ++++ config/locales/zh-CN.yml | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/organizations/teams_controller.rb b/app/controllers/organizations/teams_controller.rb index 47e95559f..5bc01fe39 100644 --- a/app/controllers/organizations/teams_controller.rb +++ b/app/controllers/organizations/teams_controller.rb @@ -4,11 +4,11 @@ class Organizations::TeamsController < Organizations::BaseController before_action :check_user_can_edit_org, only: [:create, :update, :destroy] def index - if @organization.is_owner?(current_user) || current_user.admin? + #if @organization.is_owner?(current_user) || current_user.admin? @teams = @organization.teams - else - @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) - end + #else + # @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id}) + #end @is_admin = can_edit_org? @teams = @teams.includes(:team_units, :team_users) diff --git a/app/models/organization.rb b/app/models/organization.rb index 5c66c5ff4..a541b203f 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -59,6 +59,9 @@ # class Organization < Owner + alias_attribute :name, :login + NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 + default_scope { where(type: "Organization") } has_one :organization_extension, dependent: :destroy @@ -68,6 +71,7 @@ class Organization < Owner validates :login, presence: true validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, case_sensitive: false + validates :login, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } delegate :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :num_projects, :num_users, :num_teams, to: :organization_extension, allow_nil: true diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index ab6601ed4..c040f9bd1 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -61,6 +61,8 @@ zh-CN: close_issue: 工单 activerecord: attributes: + organization: + login: '组织名称' user: login: '登录名' lastname: '姓名' From d85075f951c016209a325d9df23828d741ee2c9a Mon Sep 17 00:00:00 2001 From: viletyy Date: Sat, 6 Feb 2021 11:33:20 +0800 Subject: [PATCH 23/24] [FIX]org sync gitea_uid [FIX] --- app/services/organizations/create_service.rb | 5 +++-- app/services/repositories/create_service.rb | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/services/organizations/create_service.rb b/app/services/organizations/create_service.rb index 218fa2115..2d2b29e0f 100644 --- a/app/services/organizations/create_service.rb +++ b/app/services/organizations/create_service.rb @@ -14,7 +14,7 @@ class Organizations::CreateService < ApplicationService create_org_and_extension create_owner_info create_gitea_org - sync_owner_team_gtid + sync_gitea_info Rails.logger.info("######Organization create_service end######") end @@ -66,7 +66,8 @@ class Organizations::CreateService < ApplicationService @gitea_organization = Gitea::Organization::CreateService.call(@organization.gitea_token, organization) end - def sync_owner_team_gtid + def sync_gitea_info + organization.update!(gitea_uid: gitea_organization["id"]) owner_team.update!(gtid: gitea_organization["owner_team"]["id"]) 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 9da2fe94f..4c5519f2e 100644 --- a/app/services/repositories/create_service.rb +++ b/app/services/repositories/create_service.rb @@ -13,7 +13,6 @@ class Repositories::CreateService < ApplicationService ActiveRecord::Base.transaction do if repository.save! create_gitea_repository - create_manager_member sync_project sync_repository # if project.project_type == "common" @@ -49,6 +48,7 @@ class Repositories::CreateService < ApplicationService next unless team.includes_all_project TeamProject.build(project.user_id, team.id, project.id) end + create_manager_member end end From f06a1f63ddcc2e1947f17b6d9f2c7f44cf0d44e9 Mon Sep 17 00:00:00 2001 From: viletyy Date: Sat, 6 Feb 2021 15:40:44 +0800 Subject: [PATCH 24/24] [ADD]project transfer [FIX] [FIX] --- .gitignore | 1 + .../gitea/repository/transfer_service.rb | 27 +++++++++++ app/services/projects/transfer_service.rb | 45 +++++++++++++++++++ public/react/build | 1 - 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 app/services/gitea/repository/transfer_service.rb create mode 100644 app/services/projects/transfer_service.rb delete mode 160000 public/react/build diff --git a/.gitignore b/.gitignore index 836852ea0..77104d20a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ public/react/yarn.lock /.idea/* # Ignore react node_modules +public/react/* /public/react/.cache /public/react/node_modules/ /public/react/config/stats.json diff --git a/app/services/gitea/repository/transfer_service.rb b/app/services/gitea/repository/transfer_service.rb new file mode 100644 index 000000000..358ac9421 --- /dev/null +++ b/app/services/gitea/repository/transfer_service.rb @@ -0,0 +1,27 @@ +class Gitea::Repository::TransferService < Gitea::ClientService + attr_reader :token, :owner, :repo, :new_owner + + def initialize(token, owner, repo, new_owner) + @token = token + @owner = owner + @repo = repo + @new_owner = new_owner + end + + def call + response = post(url, request_params) + render_status(response) + end + + private + def request_params + transfer_params = { + new_owner: new_owner + } + Hash.new.merge(token: token, data: transfer_params) + end + + def url + "/repos/#{owner}/#{repo}/transfer".freeze + end +end \ No newline at end of file diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb new file mode 100644 index 000000000..f9b5c5700 --- /dev/null +++ b/app/services/projects/transfer_service.rb @@ -0,0 +1,45 @@ +class Projects::TransferService < ApplicationService + attr_accessor :project, :owner, :new_owner + + def initialize(project, new_owner) + @project = project + @owner = project.owner + @new_owner = new_owner + end + + def call + Rails.logger.info("###### Project transfer_service begin ######") + ActiveRecord::Base.transaction do + gitea_update_owner + update_owner + update_visit_teams + end + + Rails.logger.info("##### Project transfer_service end ######") + + @project.reload + end + + private + def update_owner + project.update!(user_id: new_owner.id) + end + + def update_visit_teams + if new_owner.is_a?(Organization) + new_owner.teams.where(includes_all_project: true).each do |team| + TeamProject.build(new_owner.id, team.id, project.id) + end + else + project.team_projects.each(&:destroy!) + end + end + + def gitea_update_owner + begin + 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 + end +end \ No newline at end of file diff --git a/public/react/build b/public/react/build deleted file mode 160000 index 6348a15cd..000000000 --- a/public/react/build +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6348a15cdb954862dc1b7b5f045a432bcfde7dc4