diff --git a/Gemfile.lock b/Gemfile.lock index bc10c4825..b7f060b2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,47 +1,47 @@ GEM remote: https://mirrors.cloud.tencent.com/rubygems/ specs: - aasm (5.5.0) + aasm (5.0.6) concurrent-ruby (~> 1.0) - actioncable (5.2.8.1) - actionpack (= 5.2.8.1) + actioncable (5.2.4.1) + actionpack (= 5.2.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) + actionmailer (5.2.4.1) + actionpack (= 5.2.4.1) + actionview (= 5.2.4.1) + activejob (= 5.2.4.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.8.1) - actionview (= 5.2.8.1) - activesupport (= 5.2.8.1) + actionpack (5.2.4.1) + actionview (= 5.2.4.1) + activesupport (= 5.2.4.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.8.1) - activesupport (= 5.2.8.1) + actionview (5.2.4.1) + activesupport (= 5.2.4.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - active_decorator (1.4.0) + active_decorator (1.3.2) activesupport - activejob (5.2.8.1) - activesupport (= 5.2.8.1) + activejob (5.2.4.1) + activesupport (= 5.2.4.1) globalid (>= 0.3.6) - activemodel (5.2.8.1) - activesupport (= 5.2.8.1) - activerecord (5.2.8.1) - activemodel (= 5.2.8.1) - activesupport (= 5.2.8.1) + activemodel (5.2.4.1) + activesupport (= 5.2.4.1) + activerecord (5.2.4.1) + activemodel (= 5.2.4.1) + activesupport (= 5.2.4.1) arel (>= 9.0) - activestorage (5.2.8.1) - actionpack (= 5.2.8.1) - activerecord (= 5.2.8.1) - marcel (~> 1.0.0) - activesupport (5.2.8.1) + activestorage (5.2.4.1) + actionpack (= 5.2.4.1) + activerecord (= 5.2.4.1) + marcel (~> 0.3.1) + activesupport (5.2.4.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -50,20 +50,20 @@ GEM activerecord (>= 5.0, < 6.1) acts_as_list (0.9.19) activerecord (>= 3.0) - addressable (2.8.4) - public_suffix (>= 2.0.2, < 6.0) - ancestry (4.0.0) - activerecord (>= 5.2.4.5) - annotate (2.6.7) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) + ancestry (3.0.7) + activerecord (>= 3.2.0) + annotate (2.6.5) activerecord (>= 2.3.0) - rake (~> 10.4.2, >= 10.4.2) + rake (>= 0.8.7) archive-zip (0.12.0) io-like (~> 0.3.0) arel (9.0.0) - ast (2.4.2) - autoprefixer-rails (10.4.13.0) - execjs (~> 2) - awesome_print (1.9.2) + ast (2.4.0) + autoprefixer-rails (9.7.4) + execjs + awesome_print (1.8.0) axlsx (3.0.0.pre) htmlentities (~> 4.3, >= 4.3.4) mimemagic (~> 0.3) @@ -72,40 +72,40 @@ GEM axlsx_rails (0.5.2) actionpack (>= 3.1) axlsx (>= 2.0.1) - backport (1.2.0) - benchmark (0.2.1) + backport (1.1.2) + benchmark (0.1.0) bindex (0.8.1) - bootsnap (1.12.0) - msgpack (~> 1.2) + bootsnap (1.4.6) + msgpack (~> 1.0) bootstrap (4.3.1) autoprefixer-rails (>= 9.1.0) popper_js (>= 1.14.3, < 2) sassc-rails (>= 2.0.0) builder (3.2.4) - bulk_insert (1.9.0) + bulk_insert (1.7.0) activerecord (>= 3.2.0) - capybara (3.32.2) + capybara (3.15.1) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.5) + regexp_parser (~> 1.2) xpath (~> 3.2) - chartkick (3.4.2) + chartkick (3.3.1) childprocess (3.0.0) - chinese_pinyin (1.1.0) + chinese_pinyin (1.0.2) chromedriver-helper (2.1.1) archive-zip (~> 0.10) nokogiri (~> 1.8) - chunky_png (1.4.0) - concurrent-ruby (1.2.2) - connection_pool (2.2.5) + chunky_png (1.3.11) + concurrent-ruby (1.1.6) + connection_pool (2.2.2) crass (1.0.6) deep_cloneable (3.0.0) activerecord (>= 3.1.0, < 7) - diff-lcs (1.5.0) - diffy (3.4.2) + diff-lcs (1.3) + diffy (3.3.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) doorkeeper (5.5.1) @@ -121,19 +121,19 @@ GEM elasticsearch-transport (7.5.0) faraday (>= 0.14, < 1) multi_json - enumerize (2.5.0) + enumerize (2.3.1) activesupport (>= 3.2) - erubi (1.12.0) - et-orbi (1.2.7) + erubi (1.9.0) + et-orbi (1.2.4) tzinfo - execjs (2.8.1) + execjs (2.7.0) faraday (0.15.4) multipart-post (>= 1.2, < 3) - ffi (1.15.5) + ffi (1.12.2) font-awesome-sass (4.7.0) sass (>= 3.2) - fugit (1.8.1) - et-orbi (~> 1, >= 1.2.7) + fugit (1.4.1) + et-orbi (~> 1.1, >= 1.1.8) raabro (~> 1.4) gitea-client (1.4.2) rest-client (~> 2.1.0) @@ -145,78 +145,78 @@ GEM groupdate (4.1.2) activesupport (>= 4.2) harmonious_dictionary (0.0.1) - hashie (5.0.0) + hashie (3.6.0) htmlentities (4.3.4) http-accept (1.7.0) http-cookie (1.0.5) domain_name (~> 0.5) - i18n (1.13.0) + i18n (1.8.2) concurrent-ruby (~> 1.0) io-like (0.3.1) - jaro_winkler (1.5.5) - jbuilder (2.11.5) - actionview (>= 5.0.0) + jaro_winkler (1.5.4) + jbuilder (2.10.0) activesupport (>= 5.0.0) - jquery-rails (4.5.1) + jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jwt (2.3.0) - kaminari (1.2.2) + jwt (2.2.1) + kaminari (1.2.0) activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.2) - kaminari-activerecord (= 1.2.2) - kaminari-core (= 1.2.2) - kaminari-actionview (1.2.2) + kaminari-actionview (= 1.2.0) + kaminari-activerecord (= 1.2.0) + kaminari-core (= 1.2.0) + kaminari-actionview (1.2.0) actionview - kaminari-core (= 1.2.2) - kaminari-activerecord (1.2.2) + kaminari-core (= 1.2.0) + kaminari-activerecord (1.2.0) activerecord - kaminari-core (= 1.2.2) - kaminari-core (1.2.2) - letter_avatar (0.3.9) + kaminari-core (= 1.2.0) + kaminari-core (1.2.0) + letter_avatar (0.3.8) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.20.0) + loofah (2.4.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.2) + marcel (0.3.3) + mimemagic (~> 0.3.2) maruku (0.7.3) - method_source (1.0.0) + method_source (0.9.2) mime-types (3.4.1) mime-types-data (~> 3.2015) mime-types-data (3.2023.0218.1) - mimemagic (0.4.3) + mimemagic (0.3.10) nokogiri (~> 1) rake - mini_mime (1.1.2) + mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.15.0) - msgpack (1.6.1) - multi_json (1.15.0) + minitest (5.14.0) + msgpack (1.3.3) + multi_json (1.14.1) multi_xml (0.6.0) - multipart-post (2.3.0) - mustermann (1.1.2) + multipart-post (2.1.1) + mustermann (1.1.1) ruby2_keywords (~> 0.0.1) - mysql2 (0.5.5) + mysql2 (0.5.3) netrc (0.11.0) - nio4r (2.5.9) - nokogiri (1.10.10) + nio4r (2.5.2) + nokogiri (1.10.8) mini_portile2 (~> 2.4.0) - oauth2 (1.4.8) - faraday (>= 0.8, < 3.0) + oauth2 (1.4.4) + faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.9.2) - hashie (>= 3.4.6) + omniauth (1.9.0) + hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) - omniauth-cas (2.0.0) + omniauth-cas (1.1.1) addressable (~> 2.3) nokogiri (~> 1.5) omniauth (~> 1.2) @@ -235,81 +235,85 @@ GEM omniauth-wechat-oauth2 (0.2.2) omniauth (>= 1.3.2) omniauth-oauth2 (>= 1.1.1) - parallel (1.20.1) - parser (2.7.2.0) - ast (~> 2.4.1) - pdfkit (0.8.4.3.2) - popper_js (1.16.1) - powerpack (0.1.3) - prettier (2.1.0) - public_suffix (4.0.7) - puma (5.6.5) - nio4r (~> 2.0) + parallel (1.19.1) + parser (2.7.1.1) + ast (~> 2.4.0) + pdfkit (0.8.4.1) + polyamorous (2.3.2) + activerecord (>= 5.2.1) + popper_js (1.16.0) + powerpack (0.1.2) + prettier (0.18.2) + public_suffix (4.0.3) + puma (3.12.2) raabro (1.4.0) - rack (2.0.9.3) - rack-cors (2.0.1) + rack (2.0.9) + rack-cors (1.1.1) rack (>= 2.0.0) + rack-mini-profiler (2.0.1) + rack (>= 1.2.0) rack-protection (2.0.8.1) rack - rack-test (2.1.0) - rack (>= 1.3) - rails (5.2.8.1) - actioncable (= 5.2.8.1) - actionmailer (= 5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) - activemodel (= 5.2.8.1) - activerecord (= 5.2.8.1) - activestorage (= 5.2.8.1) - activesupport (= 5.2.8.1) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.4.1) + actioncable (= 5.2.4.1) + actionmailer (= 5.2.4.1) + actionpack (= 5.2.4.1) + actionview (= 5.2.4.1) + activejob (= 5.2.4.1) + activemodel (= 5.2.4.1) + activerecord (= 5.2.4.1) + activestorage (= 5.2.4.1) + activesupport (= 5.2.4.1) bundler (>= 1.3.0) - railties (= 5.2.8.1) + railties (= 5.2.4.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) rails-i18n (5.1.3) i18n (>= 0.7, < 2) railties (>= 5.0, < 6) - railties (5.2.8.1) - actionpack (= 5.2.8.1) - activesupport (= 5.2.8.1) + railties (5.2.4.1) + actionpack (= 5.2.4.1) + activesupport (= 5.2.4.1) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) - rainbow (3.1.1) - rake (10.4.2) - ransack (2.4.1) - activerecord (>= 5.2.4) - activesupport (>= 5.2.4) + rainbow (3.0.0) + rake (13.0.1) + ransack (2.3.2) + activerecord (>= 5.2.1) + activesupport (>= 5.2.1) i18n - rb-fsevent (0.11.2) + polyamorous (= 2.3.2) + rb-fsevent (0.10.3) rb-inotify (0.10.1) ffi (~> 1.0) rchardet (1.8.0) - redcarpet (3.6.0) - redis (4.8.1) - redis-actionpack (5.3.0) - actionpack (>= 5, < 8) + redcarpet (3.5.0) + redis (4.1.3) + redis-actionpack (5.2.0) + actionpack (>= 5, < 7) redis-rack (>= 2.1.0, < 3) redis-store (>= 1.1.0, < 2) - redis-activesupport (5.3.0) - activesupport (>= 3, < 8) + redis-activesupport (5.2.0) + activesupport (>= 3, < 7) redis-store (>= 1.3, < 2) - redis-rack (2.1.4) + redis-rack (2.1.2) rack (>= 2.0.8, < 3) redis-store (>= 1.2, < 2) redis-rails (5.0.2) redis-actionpack (>= 5.0, < 6) redis-activesupport (>= 5.0, < 6) redis-store (>= 1.2, < 2) - redis-store (1.9.2) - redis (>= 4, < 6) - regexp_parser (1.8.2) - request_store (1.5.1) + redis-store (1.8.2) + redis (>= 4, < 5) + regexp_parser (1.7.0) + request_store (1.5.0) rack (>= 1.4) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) @@ -330,15 +334,15 @@ GEM rqrcode_png (0.1.5) chunky_png rqrcode - rspec-core (3.9.3) - rspec-support (~> 3.9.3) - rspec-expectations (3.9.4) + rspec-core (3.9.1) + rspec-support (~> 3.9.1) + rspec-expectations (3.9.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-rails (3.9.1) + rspec-rails (3.9.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) @@ -346,7 +350,7 @@ GEM rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) rspec-support (~> 3.9.0) - rspec-support (3.9.4) + rspec-support (3.9.2) rubocop (0.52.1) parallel (~> 1.10) parser (>= 2.4.0.2, < 3.0) @@ -355,8 +359,8 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-ole (1.2.12.2) - ruby-progressbar (1.13.0) - ruby2_keywords (0.0.5) + ruby-progressbar (1.10.1) + ruby2_keywords (0.0.2) ruby_dep (1.5.0) rubyzip (1.3.0) sass (3.7.4) @@ -364,13 +368,13 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.1.0) - railties (>= 5.2.0) + sass-rails (5.0.7) + railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sassc (2.4.0) + sassc (2.2.1) ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) @@ -378,9 +382,9 @@ GEM sprockets (> 3.0) sprockets-rails tilt - searchkick (4.6.3) - activemodel (>= 5) - elasticsearch (>= 6, < 7.14) + searchkick (3.1.3) + activemodel (>= 4.2) + elasticsearch (>= 5) hashie selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) @@ -395,10 +399,10 @@ GEM sidekiq (>= 4.2.1) sidekiq-failures (1.0.4) sidekiq (>= 4.0.0) - simple_form (5.0.3) + simple_form (5.0.2) actionpack (>= 5.0) activemodel (>= 5.0) - simple_xlsx_reader (1.0.5) + simple_xlsx_reader (1.0.4) nokogiri rubyzip sinatra (2.0.8.1) @@ -420,45 +424,46 @@ GEM thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9) - spreadsheet (1.3.0) - ruby-ole - spring (2.1.1) + spreadsheet (1.2.6) + ruby-ole (>= 1.0) + spring (2.0.2) + activesupport (>= 4.2) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.2) + sprockets-rails (3.2.1) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - thor (1.2.2) + thor (1.0.1) thread_safe (0.3.6) - tilt (2.1.0) + tilt (2.0.10) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (1.2.11) + tzinfo (1.2.6) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.8.2) - unicode-display_width (1.8.0) + unicode-display_width (1.6.1) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.7.5) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) - wkhtmltopdf-binary (0.12.6.6) + websocket-extensions (0.1.4) + wkhtmltopdf-binary (0.12.5.4) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.34) + yard (0.9.24) PLATFORMS ruby @@ -497,7 +502,6 @@ DEPENDENCIES kaminari (~> 1.1, >= 1.1.1) letter_avatar listen (>= 3.0.5, < 3.2) - loofah (~> 2.20.0) mysql2 (>= 0.4.4, < 0.6.0) oauth2 omniauth (~> 1.9.0) @@ -510,8 +514,9 @@ DEPENDENCIES parallel (~> 1.19, >= 1.19.1) pdfkit prettier - puma (~> 5.6.5) + puma (~> 3.11) rack-cors + rack-mini-profiler rails (~> 5.2.0) rails-i18n (~> 5.1) ransack @@ -533,7 +538,7 @@ DEPENDENCIES sidekiq-cron (= 1.2.0) sidekiq-failures simple_form - simple_xlsx_reader (~> 1.0.4) + simple_xlsx_reader sinatra solargraph (~> 0.38.0) spreadsheet @@ -546,4 +551,4 @@ DEPENDENCIES wkhtmltopdf-binary BUNDLED WITH - 1.17.3 + 2.1.4 diff --git a/app/assets/javascripts/admins/glcc_pr_check.js b/app/assets/javascripts/admins/glcc_pr_check.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/admins/glcc_pr_check.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/admins/identity_verifications.js b/app/assets/javascripts/admins/identity_verifications.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/admins/identity_verifications.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/admins/laboratories/edit.js b/app/assets/javascripts/admins/laboratories/edit.js index 5c2e87681..5e7b33038 100644 --- a/app/assets/javascripts/admins/laboratories/edit.js +++ b/app/assets/javascripts/admins/laboratories/edit.js @@ -63,7 +63,7 @@ $(document).on('turbolinks:load', function() { if(!valid) return; $.ajax({ - method: 'PATCH', + method: 'PUT', dataType: 'json', url: $form.attr('action'), data: new FormData($form[0]), diff --git a/app/assets/javascripts/admins/organizations/index.js b/app/assets/javascripts/admins/organizations/index.js new file mode 100644 index 000000000..97a5c76d1 --- /dev/null +++ b/app/assets/javascripts/admins/organizations/index.js @@ -0,0 +1,65 @@ +$(document).on('turbolinks:load', function(){ + if ($('body.admins-organizations-index-page').length > 0) { + var showSuccessNotify = function() { + $.notify({ + message: '操作成功' + },{ + type: 'success' + }); + } + + // organizations open cla + $('.organizations-list-container').on('click', '.open-cla-action', function(){ + var $openClaAction = $(this); + var $closeClaAction = $openClaAction.siblings('.close-cla-action'); + + var userId = $openClaAction.data('id'); + customConfirm({ + content: '确认开通吗?', + ok: function () { + $.ajax({ + url: '/admins/organizations/' + userId + '/open_cla', + method: 'POST', + dataType: 'json', + success: function() { + showSuccessNotify(); + $closeClaAction.show(); + $openClaAction.hide(); + }, + error: function(res){ + $.notify({ message: res.responseJSON.message }, { type: 'danger' }); + } + }); + } + }) + }); + + // organizations close cla + $('.organizations-list-container').on('click', '.close-cla-action', function(){ + var $closeClaAction = $(this); + var $openClaAction= $closeClaAction.siblings('.open-cla-action'); + + var userId = $openClaAction.data('id'); + customConfirm({ + content: '确认关闭吗?', + ok: function () { + $.ajax({ + url: '/admins/organizations/' + userId + '/close_cla', + method: 'POST', + dataType: 'json', + success: function() { + showSuccessNotify(); + $openClaAction.show(); + $closeClaAction.hide(); + }, + error: function(res){ + $.notify({ message: res.responseJSON.message }, { type: 'danger' }); + } + }); + } + }) + }); + + + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admins/page_themes.js b/app/assets/javascripts/admins/page_themes.js new file mode 100644 index 000000000..1663fb90a --- /dev/null +++ b/app/assets/javascripts/admins/page_themes.js @@ -0,0 +1,3 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. + diff --git a/app/assets/javascripts/admins/site_pages.js b/app/assets/javascripts/admins/site_pages.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/admins/site_pages.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/identity_verifications.js b/app/assets/javascripts/identity_verifications.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/identity_verifications.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/organizations/clas.js b/app/assets/javascripts/organizations/clas.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/organizations/clas.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/pages.js b/app/assets/javascripts/pages.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/pages.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/users/clas.js b/app/assets/javascripts/users/clas.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/users/clas.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/admins/glcc_pr_check.scss b/app/assets/stylesheets/admins/glcc_pr_check.scss new file mode 100644 index 000000000..7dfa6e7cf --- /dev/null +++ b/app/assets/stylesheets/admins/glcc_pr_check.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admins/glcc_pr_check controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/admins/identity_verifications.scss b/app/assets/stylesheets/admins/identity_verifications.scss new file mode 100644 index 000000000..c26986f12 --- /dev/null +++ b/app/assets/stylesheets/admins/identity_verifications.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admins/identity_verifications controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/admins/page_themes.scss b/app/assets/stylesheets/admins/page_themes.scss new file mode 100644 index 000000000..b47fedabf --- /dev/null +++ b/app/assets/stylesheets/admins/page_themes.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admins/page_themes controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/admins/site_pages.scss b/app/assets/stylesheets/admins/site_pages.scss new file mode 100644 index 000000000..f84f347b4 --- /dev/null +++ b/app/assets/stylesheets/admins/site_pages.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admins/site_pages controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/identity_verifications.scss b/app/assets/stylesheets/identity_verifications.scss new file mode 100644 index 000000000..f2edc1e20 --- /dev/null +++ b/app/assets/stylesheets/identity_verifications.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the identity_verifications controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/organizations/clas.scss b/app/assets/stylesheets/organizations/clas.scss new file mode 100644 index 000000000..1716eff69 --- /dev/null +++ b/app/assets/stylesheets/organizations/clas.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the organizations/clas controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/pages.scss b/app/assets/stylesheets/pages.scss new file mode 100644 index 000000000..0d6878aa1 --- /dev/null +++ b/app/assets/stylesheets/pages.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the pages controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/users/clas.scss b/app/assets/stylesheets/users/clas.scss new file mode 100644 index 000000000..c5dd66bb9 --- /dev/null +++ b/app/assets/stylesheets/users/clas.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the users/clas controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 889fc8b97..ea26f1bd5 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -4,15 +4,16 @@ class AccountsController < ApplicationController #skip_before_action :check_account, :only => [:logout] - def simple_update + def simple_update simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, "")) simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, "")) simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, "")) - Register::RemoteForm.new(simple_update_params).validate! + Register::RemoteForm.new(simple_update_params.merge(user_id: current_user.id)).validate! ActiveRecord::Base.transaction do result = auto_update(current_user, simple_update_params) if result[:message].blank? + UserAction.create(:action_id => current_user.id, :action_type => "sync_educoder_user", :user_id => current_user.id, :ip => request.remote_ip) if params[:platform] == "educoder" render_ok else render_error(result[:message]) @@ -160,8 +161,11 @@ class AccountsController < ApplicationController successful_authentication(user) render_ok end + elsif interactor.result[:message].to_s.include?("user already exists") + UserAction.create(:action_id => 2, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};") + normal_status(-1, "用户已注册,请勿连续操作。") else - tip_exception(-1, interactor.error) + tip_exception(-1, interactor.result[:message]) end rescue Register::BaseForm::EmailError => e render_result(-2, e.message) @@ -176,9 +180,14 @@ class AccountsController < ApplicationController rescue Register::BaseForm::VerifiCodeError => e render_result(-6, e.message) rescue Exception => e - Gitea::User::DeleteService.call(user.login) unless user.nil? - uid_logger_error(e.message) - tip_exception(-1, e.message) + if user.present? && !e.message.to_s.include?("user already exists") + # Gitea::User::DeleteService.call(user.login) + # user.destroy + end + Rails.logger.error("##:register error--#{user.try(:id)},message:#{e.message}") + UserAction.create(:action_id => 1, :action_type => "register_error", :user_id => user.try(:id).to_i, :ip => "code: #{register_params[:code]}; login: #{register_params[:login]}; namespace: #{register_params[:namespace]}; password: #{password};") + logger_error(e) + tip_exception(-1, "注册失败") end end @@ -350,6 +359,17 @@ class AccountsController < ApplicationController Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate! render_ok end + + def check_keywords + text = params[:text].to_s.each_char.select { |c| c.bytes.first < 240 }.join('') + data = ! ReversedKeyword.check_exists?(text) + result = { + status: 0, + data: data, + message: data ? "" : "无法使用以下关键词:#{text},请重新命名" + } + render_ok(result) + end private diff --git a/app/controllers/admins/glcc_pr_check_controller.rb b/app/controllers/admins/glcc_pr_check_controller.rb new file mode 100644 index 000000000..1d79ba802 --- /dev/null +++ b/app/controllers/admins/glcc_pr_check_controller.rb @@ -0,0 +1,32 @@ +class Admins::GlccPrCheckController < Admins::BaseController + def index + params[:sort_by] = params[:sort_by].presence || 'created_on' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + examine_materials = Admins::GlccExamineMaterial.call(params) + @examine_materials = paginate examine_materials.includes(:glcc_student) + end + + def send_mail + year = if params[:date].present? + params[:date][:year] + end + if year.nil? + return redirect_to admins_glcc_pr_check_index_path + flash[:error] = "时间不能为空" + end + if params[:term].blank? + return redirect_to admins_glcc_pr_check_index_path + flash[:error] = "考核选项不能为空" + end + + examine_materials = GlccMediumTermExamineMaterial.where(\ + term: params[:term], + created_on: [Time.now.change(year:year).beginning_of_year .. Time.now.change(year:year).end_of_year] + ) + examine_materials.map{ |e| + e.send_mail + } + flash[:danger] = "#{year} 年 #{params[:term].to_i == 1 ? "中期考核": "结项考核"} PR 检测邮件已全部发送完毕,一共#{examine_materials.count}封邮件" + redirect_to admins_glcc_pr_check_index_path + end +end diff --git a/app/controllers/admins/identity_verifications_controller.rb b/app/controllers/admins/identity_verifications_controller.rb new file mode 100644 index 000000000..51d5e423c --- /dev/null +++ b/app/controllers/admins/identity_verifications_controller.rb @@ -0,0 +1,35 @@ +class Admins::IdentityVerificationsController < Admins::BaseController + before_action :finder_identity_verification, except: [:index] + def index + params[:sort_by] = params[:sort_by].presence || 'created_at' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + identity_verifications = Admins::IdentityVerificationQuery.call(params) + @identity_verifications = paginate identity_verifications.preload(:user) + end + + def show + render 'edit' + end + def edit + end + + def update + if @identity_verification.update(update_params) + redirect_to admins_identity_verifications_path + flash[:success] = "更新成功" + else + redirect_to admins_identity_verifications_path + flash[:danger] = "更新失败" + end + end + + private + def finder_identity_verification + @identity_verification = IdentityVerification.find(params[:id]) + @user = @identity_verification.user + end + + def update_params + params.require(:identity_verification).permit(:state, :description) + end +end diff --git a/app/controllers/admins/laboratory_settings_controller.rb b/app/controllers/admins/laboratory_settings_controller.rb index 861db50c6..d522a479b 100644 --- a/app/controllers/admins/laboratory_settings_controller.rb +++ b/app/controllers/admins/laboratory_settings_controller.rb @@ -25,6 +25,6 @@ class Admins::LaboratorySettingsController < Admins::BaseController params.permit(:identifier, :name, :nav_logo, :login_logo, :tab_logo, :oj_banner, :subject_banner, :course_banner, :competition_banner, :moop_cases_banner, - :footer, navbar: %i[name link hidden]) + :footer, navbar: %i[name link hidden index]) end end \ No newline at end of file diff --git a/app/controllers/admins/message_templates_controller.rb b/app/controllers/admins/message_templates_controller.rb index 87a3ccfe7..6a5000c24 100644 --- a/app/controllers/admins/message_templates_controller.rb +++ b/app/controllers/admins/message_templates_controller.rb @@ -49,7 +49,7 @@ class Admins::MessageTemplatesController < Admins::BaseController def message_template_params # type = @message_template.present? ? @message_template.type : "MessageTemplate::CustomTip" # params.require(type.split("::").join("_").underscore.to_sym).permit! - params.require(:message_template).permit! + params.require(:message_template_custom_tip).permit! end def get_template diff --git a/app/controllers/admins/organizations_controller.rb b/app/controllers/admins/organizations_controller.rb index 35fb4dee8..3d4eac4c6 100644 --- a/app/controllers/admins/organizations_controller.rb +++ b/app/controllers/admins/organizations_controller.rb @@ -9,12 +9,29 @@ class Admins::OrganizationsController < Admins::BaseController @orgs = paginate orgs end + + def open_cla + @org.open_cla! + render_ok + end + + def close_cla + if @org.cla.nil? + @org.close_cla! + render_ok + else + render_error(' 该组织已创建CLA 不允许关闭') + end + + end + def show end def destroy @org.destroy! Admins::DeleteOrganizationService.call(@org.login) + UserAction.create(action_id: @org.id, action_type: "DestroyOrganization", user_id: current_user.id, :ip => request.remote_ip, data_bank: @org.attributes.to_json) render_delete_success end diff --git a/app/controllers/admins/page_themes_controller.rb b/app/controllers/admins/page_themes_controller.rb new file mode 100644 index 000000000..1b2cd8ebe --- /dev/null +++ b/app/controllers/admins/page_themes_controller.rb @@ -0,0 +1,79 @@ +class Admins::PageThemesController < Admins::BaseController + before_action :finder_page_theme, only: [:edit, :update, :destroy] + + def index + params[:sort_by] = params[:sort_by].presence || 'created_at' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + + page_themes = Admins::PageThemesQuery.call(params) + + @page_themes = paginate page_themes + end + + def show + render 'edit' + end + + def edit + end + + def create + @page_theme = PageTheme.new theme_params + if @page_theme.save + save_image_file(params[:image]) + redirect_to admins_page_themes_path + flash[:success] = "新增主题成功" + else + redirect_to admins_page_themes_path + flash[:danger] = "新增主题失败: #{@page_theme.errors.messages.values.flatten.join(',')}" + end + end + + def destroy + if PageTheme.where(language_frame: @page_theme.language_frame).count <= 1 + flash[:danger] = "删除主题失败,必须存在一个主题" + return redirect_to admins_page_themes_path + end + + if @page_theme.destroy + redirect_to admins_page_themes_path + flash[:success] = "删除主题成功" + else + redirect_to admins_page_themes_path + flash[:danger] = "删除主题失败" + end + end + + def new + @page_theme = PageTheme.new + end + + def update + @page_theme.attributes = theme_params + if @page_theme.save + save_image_file(params[:image]) + redirect_to admins_page_themes_path + flash[:success] = "更新成功" + else + redirect_to admins_page_themes_path + flash[:danger] = "更新失败" + end + end + + private + def finder_page_theme + @page_theme = PageTheme.find(params[:id]) + end + + def theme_params + params.require(:page_theme).permit(:language_frame, :name, :cate, :image_url, :clone_url, :order_index) + end + + def save_image_file(file) + return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile) + file_path = Util::FileManage.source_disk_filename(@page_theme, "image") + File.delete(file_path) if File.exist?(file_path) # 删除之前的文件 + Util.write_file(file, file_path) + end + +end diff --git a/app/controllers/admins/projects_controller.rb b/app/controllers/admins/projects_controller.rb index 4175f7250..f1f797043 100644 --- a/app/controllers/admins/projects_controller.rb +++ b/app/controllers/admins/projects_controller.rb @@ -35,6 +35,7 @@ class Admins::ProjectsController < Admins::BaseController Gitea::Repository::DeleteService.new(project.owner, project.identifier).call project.destroy! # render_delete_success + UserAction.create(action_id: project.id, action_type: "DestroyProject", user_id: current_user.id, :ip => request.remote_ip, data_bank: project.attributes.to_json) redirect_to admins_projects_path flash[:success] = "删除成功" end diff --git a/app/controllers/admins/site_pages_controller.rb b/app/controllers/admins/site_pages_controller.rb new file mode 100644 index 000000000..f0e05e71d --- /dev/null +++ b/app/controllers/admins/site_pages_controller.rb @@ -0,0 +1,46 @@ +class Admins::SitePagesController < Admins::BaseController + before_action :finder_site_page, except: [:index] + + def index + params[:sort_by] = params[:sort_by].presence || 'created_at' + params[:sort_direction] = params[:sort_direction].presence || 'desc' + + pages = Admins::SitePagesQuery.call(params) + + @site_pages = paginate pages.preload(:user) + end + + def show + render 'edit' + end + + def edit + end + + + def destroy + if @site_page.destroy + redirect_to admins_site_pages_path + flash[:success] = "删除站点成功" + else + redirect_to admins_site_pages_path + flash[:danger] = "删除站点失败" + end + end + + def update + @site_page.update(update_params) + flash[:success] = '保存成功' + render 'edit' + end + + private + def finder_site_page + @site_page = Page.find(params[:id]) + @user = @site_page.user + end + + def update_params + params.require(:page).permit(:state, :state_description) + end +end diff --git a/app/controllers/admins/users_controller.rb b/app/controllers/admins/users_controller.rb index 9137e218e..e15e39242 100644 --- a/app/controllers/admins/users_controller.rb +++ b/app/controllers/admins/users_controller.rb @@ -1,5 +1,5 @@ class Admins::UsersController < Admins::BaseController - before_action :finder_user, except: [:index] + before_action :finder_user, except: [:index] def index params[:sort_by] = params[:sort_by].presence || 'created_on' @@ -25,15 +25,16 @@ class Admins::UsersController < Admins::BaseController end def destroy + UserAction.create(action_id: @user.id, action_type: "DestroyUser", user_id: current_user.id, :ip => request.remote_ip, data_bank: @user.attributes.to_json) @user.destroy! Gitea::User::DeleteService.call(@user.login) - + render_delete_success end def lock @user.lock! - + UserAction.create(action_id: @user.id, action_type: "LockUser", user_id: current_user.id, :ip => request.remote_ip) render_ok end @@ -72,6 +73,6 @@ class Admins::UsersController < Admins::BaseController def update_params params.require(:user).permit(%i[lastname nickname gender technical_title is_shixun_marker mail phone location location_city school_id department_id admin - password login]) + password login website_permission]) end end diff --git a/app/controllers/api/v1/projects/branches_controller.rb b/app/controllers/api/v1/projects/branches_controller.rb index 0c89f6012..40f44fea5 100644 --- a/app/controllers/api/v1/projects/branches_controller.rb +++ b/app/controllers/api/v1/projects/branches_controller.rb @@ -17,7 +17,16 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController def destroy @result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token) - if @result_object + if @result_object + # 有开启的pr需要一同关闭 + # 1、删除本仓库中存在未关闭的pr,即本仓库分支1->分支2 + # 2、如果是fork仓库,考虑删除主仓库中存在未关闭的pr,即本仓库:分支1->主:分支2,同时分两种删除:1删除本仓库分支1,2删除主仓库分支2 + close_pull_requests_by(@project, params[:name]) + if @project.forked_from_project_id.present? + # fork项目中删除分支 + close_pull_requests_by(@project.fork_project, params[:name]) + end + return render_ok else return render_error('删除分支失败!') @@ -39,4 +48,19 @@ class Api::V1::Projects::BranchesController < Api::V1::BaseController def branch_params params.require(:branch).permit(:new_branch_name, :old_branch_name) end + + def close_pull_requests_by(project, branch_name) + open_pull_requests = project.pull_requests.opening.where(head: branch_name).or(project.pull_requests.opening.where(base: branch_name)) + if open_pull_requests.present? + open_pull_requests.each do |pull_request| + closed = PullRequests::CloseService.call(project.owner, project.repository, pull_request, current_user) + if closed === true + pull_request.project_trends.create!(user: current_user, project: project,action_type: ProjectTrend::CLOSE) + # 合并请求下issue处理为关闭 + pull_request.issue&.update_attributes!({status_id:5}) + SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, pull_request.id) if Site.has_notice_menu? + end + end + end + end end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cd1219006..bcfef8792 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -81,7 +81,7 @@ class ApplicationController < ActionController::Base # 判断用户的邮箱或者手机是否可用 # params[:type] 1: 注册;2:忘记密码;3:绑定 def check_mail_and_phone_valid login, type - unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/ + unless login =~ /\A[a-zA-Z0-9]+([._\-\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/ || login =~ /^1\d{10}$/ tip_exception(-2, "请输入正确的手机号或邮箱") end @@ -1103,7 +1103,7 @@ class ApplicationController < ActionController::Base "author_time": commit['commit']['author']['date'], "committer_time": commit['commit']['committer']['date'], "content": commit['commit']['message'], - "commit_diff": commit_diff['Files'].to_s + "commit_diff": commit_diff.present? ? commit_diff['Files'].to_s : "" }.to_json resp_body = Blockchain::InvokeBlockchainApi.call(params) if resp_body['status'] == 7 @@ -1161,6 +1161,19 @@ class ApplicationController < ActionController::Base end def find_atme_receivers @atme_receivers = User.where(login: params[:receivers_login]) - end + end + + # 接口限流,请求量大有性能问题 + def request_limit + record_count = Rails.cache.read("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}") + if record_count.present? + record_count = record_count + 1 + else + record_count = 1 + end + tip_exception("请求太快,请稍后再试。") if record_count > 100 + + Rails.cache.write("request/#{controller_name}/#{Time.now.strftime('%Y%m%d%H%M')}/#{request.remote_ip}", record_count, expires_in: 1.minute) + end end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 0cdba3847..4949946c0 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -38,12 +38,13 @@ class AttachmentsController < ApplicationController url = ("/repos"+url.split(base_url + "/api")[1]) filepath, ref = url.split("/")[-1].split("?") url.gsub!(url.split("/")[-1], '') - puts filepath - request_url = [domain, api_url, url, CGI.escape(filepath), "?ref=#{CGI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join + Rails.logger.info("url===#{url}") + request_url = [domain, api_url, URI.encode(url), CGI.escape(filepath), "?ref=#{CGI.escape(ref.split('ref=')[1])}&access_token=#{User.where(admin: true).take&.gitea_token}"].join + Rails.logger.info("request_url===#{request_url}") response = Faraday.get(request_url) filename = filepath else - response = Faraday.get(url) + response = Faraday.get(URI.encode(url)) filename = params[:download_url].to_s.split("/").pop() end send_data(response.body.force_encoding("UTF-8"), filename: filename, type: "application/octet-stream", disposition: 'attachment') diff --git a/app/controllers/forks_controller.rb b/app/controllers/forks_controller.rb index c740c8b03..a27f6668d 100644 --- a/app/controllers/forks_controller.rb +++ b/app/controllers/forks_controller.rb @@ -5,13 +5,17 @@ class ForksController < ApplicationController before_action :authenticate_project!, :authenticate_user! def create - @new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call + @new_project = Projects::ForkService.new(current_user, @project, params[:organization], params[:new_name], params[:new_identifier]).call end private def authenticate_project! if current_user&.id == @project.user_id render_result(-1, "自己不能fork自己的项目") + elsif @project.fork_users.where(user_id: current_user.id).present? + fork = @project.fork_users.find_by(user_id: current_user.id) + render json: { status: 0, id: fork.fork_project_id, identifier: fork.fork_project&.identifier, message: "fork失败,你已拥有了这个项目 #{fork.fork_project&.identifier}" } + return elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier) render_result(0, "fork失败,你已拥有了这个项目") end @@ -24,4 +28,4 @@ class ForksController < ApplicationController return if @project.member?(current_user) || current_user.admin? render_forbidden('你没有权限操作') end -end +end \ No newline at end of file diff --git a/app/controllers/identity_verifications_controller.rb b/app/controllers/identity_verifications_controller.rb new file mode 100644 index 000000000..4542163ab --- /dev/null +++ b/app/controllers/identity_verifications_controller.rb @@ -0,0 +1,29 @@ +class IdentityVerificationsController < ApplicationController + before_action :require_login + before_action :require_profile_completed, only: [:create] + + def index + @id_verify = current_user.identity_verification + return render_ok({data:nil}) unless @id_verify + end + + def create + return tip_exception(-1, "您已提交过身份审核,请勿重复提交") if IdentityVerification.exists?(user:current_user) + return tip_exception(-1, "身份证输入有误")unless create_params[:number] =~ User::VALID_NUMBER_REGEX + @id_verify = IdentityVerification.new(create_params) + @id_verify.user = current_user + @id_verify.save + end + + def update + return tip_exception(-1, "身份证输入有误")unless create_params[:number] =~ User::VALID_NUMBER_REGEX + current_user.identity_verification.update(create_params.merge({ state: 0 })) + current_user.update(id_card_verify: false) + @id_verify = current_user.identity_verification + end + + private + def create_params + params.permit(:number, :name, :card_front, :card_back, :hold_card_front, :hold_card_back) + end +end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index c1f2ea1f0..0015b518e 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,12 +1,12 @@ class IssuesController < ApplicationController - before_action :require_login, except: [:index, :show, :index_chosen] + before_action :require_login, except: [:index, :show, :index_chosen, :index_to_name] before_action :require_profile_completed, only: [:create] before_action :load_project before_action :set_user before_action :check_menu_authorize, except: [:index_chosen] before_action :check_issue_permission before_action :operate_issue_permission, only:[:create, :update, :destroy, :clean, :series_update, :copy] - before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue] + before_action :check_project_public, only: [:index ,:show, :copy, :index_chosen, :close_issue, :index_to_name] before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue] before_action :check_token_enough, :find_atme_receivers, only: [:create, :update] @@ -49,6 +49,27 @@ class IssuesController < ApplicationController @issue_chosen = issue_left_chosen(@project, nil) end + def index_to_name + issues_index = params[:index].map(&:to_i) + exit_index = [] + issues_result = @project.issues.where(project_issues_index:issues_index).map{ |e| + exit_index << e.project_issues_index + { + id:e.id, + project_issues_index:e.project_issues_index, + subject:e.subject + } + + } + not_exit = issues_index - exit_index + not_exit.map{|e| + issues_result << {id: nil, + project_issues_index:e, + subject: nil} + } + render json: issues_result + end + def commit_issues issues = @project.issues.issue_issue.includes(:user,:tracker) issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user)) diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index afe767897..da8ad26cb 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -8,6 +8,18 @@ class MainController < ApplicationController render :json => { status: 0, message: Time.now.to_i } end + def test_404 + status_code = 404 + status = status_code.to_s + fname = %w[404 403 422 500].include?(status) ? status : "unknown" + + respond_to do |format| + format.html { render template: "/shared/#{fname}", handler: [:erb], status: status } + format.xml { render :xml => Laboratory.limit(1).to_xml, status: status } + format.all { render body: nil, status: status } + end + end + def index domain_session = params[:_educoder_session] if domain_session @@ -24,6 +36,8 @@ class MainController < ApplicationController # TODO: 这块之后需要整合,者架构重新变化,统一跳转到index后再路由分发 if params[:path] && params[:path]&.include?("h5educoderbuild") && params[:path].split("/").first == "h5educoderbuild" render file: 'public/h5educoderbuild/index.html', :layout => false, :content_type=> 'text/html' + elsif params[:path].to_s.include?("test_404") + test_404 else render file: 'public/react/build/index.html', :layout => false, :content_type=> 'text/html' end diff --git a/app/controllers/organizations/clas_controller.rb b/app/controllers/organizations/clas_controller.rb new file mode 100644 index 000000000..cc3f4e11f --- /dev/null +++ b/app/controllers/organizations/clas_controller.rb @@ -0,0 +1,70 @@ +class Organizations::ClasController < Organizations::BaseController + before_action :load_organization + before_action :load_cla, only: [:show, :update, :destroy] + before_action :check_user_can_edit_org, only: [:create, :update, :destroy] + + def index + @cla = @organization.cla + end + + def show + @is_admin = can_edit_org? + @is_member = @organization.is_member?(current_user.id) + @is_sign = @organization.is_sign?(current_user.id) + @cla_sign_email = if @is_sign + @organization.cla_sign_email(current_user.id) + end + end + + def create + tip_exception("您的组织还未拥有创建CLA权限,请联系管理员") if @organization.enabling_cla == false + ActiveRecord::Base.transaction do + if @organization.cla.present? + return tip_exception("组织已存在CLA!") + else + Organizations::CreateClaForm.new(cla_params).validate! + @cla = Cla.build(cla_params,@organization.id) + end + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def update + ActiveRecord::Base.transaction do + Organizations::CreateClaForm.new(cla_params).validate! + @cla.update(cla_params) + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + tip_exception("组织CLA已被签署,无法删除") if @cla.user_clas.size > 0 + ActiveRecord::Base.transaction do + @cla.destroy! + end + render_ok + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + + private + def cla_params + params.permit(:name, :key, :content, :pr_need) + end + + def load_organization + @organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id]) + return render_not_found("组织不存在") if @organization.nil? + end + + def load_cla + @cla = Cla.find_by!(organization:@organization, key: params[:id]) + end + +end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 5bd4aae3a..74560663d 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -4,11 +4,12 @@ class ProjectsController < ApplicationController include ProjectsHelper include Acceleratorable - before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list] - before_action :require_profile_completed, only: [:create, :migrate] - before_action :load_repository, except: %i[index group_type_list migrate create recommend banner_recommend] + before_action :require_login, except: %i[index branches branches_slice group_type_list simple show fork_users praise_users watch_users recommend banner_recommend about menu_list verify_auth_token] + before_action :require_profile_completed, only: [:create, :migrate,:page_migrate,:verify_auth_token] + before_action :load_repository, except: %i[index group_type_list migrate page_migrate create recommend banner_recommend verify_auth_token] before_action :authorizate_user_can_edit_project!, only: %i[update] before_action :project_public?, only: %i[fork_users praise_users watch_users] + before_action :request_limit, only: %i[index] def menu_list menu = [] @@ -42,11 +43,11 @@ class ProjectsController < ApplicationController if category_id.blank? && params[:search].blank? && params[:topic_id].blank? # 默认查询时count性能问题处理 ProjectCategory.sum("projects_count") - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").count - elsif params[:search].present? || params[:topic_id].present? + elsif params[:search].present? || params[:topic_id].present? @projects.total_count else - cate = ProjectCategory.find_by(id: category_id) - cate&.projects_count || 0 + cate = ProjectCategory.find_by(id: category_id) + cate&.projects_count || 0 end end @@ -54,26 +55,32 @@ class ProjectsController < ApplicationController ActiveRecord::Base.transaction do Projects::CreateForm.new(project_params).validate! @project = Projects::CreateService.new(current_user, project_params).call - # OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id) + #OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id) + UpdateProjectTopicJob.perform_later(@project.id) if @project.id.present? end rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) end + def verify_auth_token + data = Projects::VerifyAuthTokenService.call(params[:clone_addr], params[:auth_token]) + render_ok({data: data}) + end + def migrate Projects::MigrateForm.new(mirror_params).validate! - @project = + @project = if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr]) source_clone_url = mirror_params[:clone_addr] uid_logger("########## 已动加速器 ##########") result = Gitea::Accelerator::MigrateService.call(mirror_params) if result[:status] == :success Rails.logger.info "########## 加速镜像成功 ########## " - Projects::MigrateService.call(current_user, - mirror_params.merge(source_clone_url: source_clone_url, - clone_addr: accelerator_url(mirror_params[:repository_name]))) + Projects::MigrateService.call(current_user, + mirror_params.merge(source_clone_url: source_clone_url, + clone_addr: accelerator_url(mirror_params[:repository_name]))) else Projects::MigrateService.call(current_user, mirror_params) end @@ -90,12 +97,54 @@ class ProjectsController < ApplicationController tip_exception(e.message) end + + def page_migrate + return normal_status(-1, "您还未开通Page服务,无法进行新建站点") unless current_user.id_card_verify + return normal_status(-1, "你已使用了 #{page_site_params[:identifier]} 作为page标识") if Page.exists?(identifier: page_site_params[:identifier], user: current_user) + + Projects::MigrateForm.new(mirror_params).validate! + + @project = + if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr]) + source_clone_url = mirror_params[:clone_addr] + uid_logger("########## 已动加速器 ##########") + result = Gitea::Accelerator::MigrateService.call(mirror_params) + if result[:status] == :success + Rails.logger.info "########## 加速镜像成功 ########## " + Projects::MigrateService.call(current_user, + mirror_params.merge(source_clone_url: source_clone_url, + clone_addr: accelerator_url(mirror_params[:repository_name]))) + else + Projects::MigrateService.call(current_user, mirror_params) + end + elsif EduSetting.get("mirror_address").to_s.include?("cnpmjs") && mirror_params[:clone_addr].include?("github.com") + source_clone_url = mirror_params[:clone_addr] + clone_url = source_clone_url.gsub('github.com', 'github.com.cnpmjs.org') + uid_logger("########## 更改clone_addr ##########") + Projects::MigrateService.call(current_user, mirror_params.merge(source_clone_url: source_clone_url, clone_addr: clone_url)) + else + Projects::MigrateService.call(current_user, mirror_params) + end + if @project.present? + page = Page.new page_site_params + page.user = current_user + page.project = @project + end + + if page.save + render json: page + end + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + def branches return @branches = [] unless @project.forge? # result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier) result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier, params[:name]) - @branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result) : result + @branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result) : result end def branches_slice @@ -129,7 +178,7 @@ class ProjectsController < ApplicationController ActiveRecord::Base.transaction do # TODO: # 临时特殊处理修改website、lesson_url操作方法 - if project_params.has_key?("website") + if project_params.has_key?("website") if params[:project_topic_names].is_a?(Array) ProjectTopicRalate.where(project: @project).destroy_all params[:project_topic_names].each do |name| @@ -145,11 +194,11 @@ class ProjectsController < ApplicationController } Gitea::Repository::UpdateService.call(@owner, @project.identifier, gitea_params) else - validate_params = project_params.slice(:name, :description, - :project_category_id, :project_language_id, :private, :identifier) - + validate_params = project_params.slice(:name, :description, + :project_category_id, :project_language_id, :private, :identifier) + Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate! - + private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false new_project_params = project_params.except(:private).merge(is_public: !private) @@ -162,7 +211,7 @@ class ProjectsController < ApplicationController name: @project.identifier } gitea_repo = Gitea::Repository::UpdateService.call(@owner, @project&.repository&.identifier, gitea_params) - @project.repository.update_attributes({hidden: gitea_repo["private"], identifier: gitea_repo["name"]}) + @project.repository.update_attributes({ hidden: gitea_repo["private"], identifier: gitea_repo["name"] }) # 更新对应所属分类下的项目数量(私有) before_is_public = @project.previous_changes[:is_public].present? ? @project.previous_changes[:is_public][0] : @project.is_public after_is_public = @project.previous_changes[:is_public].present? ? @project.previous_changes[:is_public][1] : @project.is_public @@ -203,13 +252,13 @@ class ProjectsController < ApplicationController def quit user_is_admin = current_user.admin? || @project.manager?(current_user) - if !user_is_admin && @project.member(current_user.id) && @project.forge? + if !user_is_admin && @project.member(current_user.id) && @project.forge? ActiveRecord::Base.transaction do Projects::DeleteMemberInteractor.call(@project.owner, @project, current_user) SendTemplateMessageJob.perform_later('ProjectMemberLeft', current_user.id, current_user.id, @project.id) if Site.has_notice_menu? render_ok end - else + else render_forbidden('你不能退出该仓库') end rescue Exception => e @@ -238,6 +287,13 @@ class ProjectsController < ApplicationController def simple # 为了缓存活跃项目的基本信息,后续删除 Cache::V2::ProjectCommonService.new(@project.id).read + # 项目名称,标识,所有者变化时重置缓存 + project_common = $redis_cache.hgetall("v2-project-common:#{@project.id}") + if project_common.present? + if project_common["name"] != @project.name || project_common["identifier"] != @project.identifier || project_common["owner_id"] != @project.user_id + Cache::V2::ProjectCommonService.new(@project.id).reset + end + end json_response(@project, current_user) end @@ -266,7 +322,7 @@ class ProjectsController < ApplicationController if @project_detail.save! attachment_ids = Array(params[:attachment_ids]) logger.info "=============> #{Array(params[:attachment_ids])}" - @attachments = Attachment.where(id: attachment_ids) + @attachments = Attachment.where(id: attachment_ids) @attachments.update_all( container_id: @project_detail.id, container_type: @project_detail.model_name.name, @@ -279,17 +335,22 @@ class ProjectsController < ApplicationController private + def project_params params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url, :default_branch, :identifier, :project_category_id, :project_language_id, :license_id, :ignore_id, :private, - :blockchain, :blockchain_token_all, :blockchain_init_token) + :blockchain, :blockchain_token_all, :blockchain_init_token, :pr_view_admin) end def mirror_params - params.permit(:user_id, :name, :description, :repository_name, :is_mirror, :auth_username, + params.permit(:user_id, :name, :description, :repository_name, :is_mirror, :auth_username, :auth_token, :auth_password, :project_category_id, :project_language_id, :clone_addr, :private) end + def page_site_params + params.permit(:site_name, :identifier,:language_frame,:theme) + end + def project_public? return if @project.is_public? diff --git a/app/controllers/pull_requests_controller.rb b/app/controllers/pull_requests_controller.rb index f1039362d..037e201bf 100644 --- a/app/controllers/pull_requests_controller.rb +++ b/app/controllers/pull_requests_controller.rb @@ -67,6 +67,7 @@ class PullRequestsController < ApplicationController Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate! @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) if @gitea_pull_request[:status] == :success + PullRequests::SendJournalService.call(@project, @pull_request, current_user) @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) reviewers = User.where(id: params[:reviewer_ids]) @pull_request.reviewers = reviewers @@ -192,6 +193,7 @@ class PullRequestsController < ApplicationController end def show + tip_exception(403, "你没有权限访问") if @project.pr_view_admin? && !@project.manager?(current_user) @issue_user = @issue.user @issue_assign_to = @issue.get_assign_user @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 6b2d2437a..e26559f74 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -176,6 +176,9 @@ class RepositoriesController < ApplicationController result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier, {page: params[:page], limit: params[:limit]}) @total_count = result[:total_count] @contributors = result.is_a?(Hash) ? result[:body] : [] + + add_contributors_count = EduSetting.get("ProjectAddContributors-#{@project.id}") + @total_count = @total_count + add_contributors_count.to_i end rescue @contributors = [] @@ -263,8 +266,9 @@ class RepositoriesController < ApplicationController end @path = GiteaService.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/" @readme = result[:status] === :success ? result[:body] : nil - @readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path) + # replace_content 前置,防止被content改写 @readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) + @readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path) render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha", "replace_content") rescue render json: nil diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 252bb6a9a..dd8c9ddcf 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -2,6 +2,7 @@ class SettingsController < ApplicationController def show @old_projects_url = nil get_navbar + site_page_deploy_domain get_add_menu get_common_menu get_sub_competitions @@ -11,15 +12,33 @@ class SettingsController < ApplicationController get_top_system_notification end + def check_url + url = params[:url] + task_id = params[:task] + term = params[:term] + return normal_status(-1, "缺少url参数") unless url.present? + return normal_status(-1, "缺少term参数") unless term.present? + return normal_status(-1, "缺少task参数") unless task_id.present? + glcc_mate = GlccMediumTermExamineMaterial.new(code_or_pr_url: url, task_id: task_id, term: term, created_on:Time.now) + state = glcc_mate.check_pr_url + errors = glcc_mate.gennerate_content(state) + render_ok({ state:state, state_html: errors}) + end + + private def get_navbar - @navbar = default_laboratory.navbar - if User.current.logged? - pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false} - @navbar << pernal_index - end + @navbar = default_laboratory.navbar.sort_by{|e| e["index"].to_i } + # if User.current.logged? + # pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false} + # @navbar << pernal_index + # end end + def site_page_deploy_domain + @deploy_domain = EduSetting.find_by_name("site_page_deploy_domain").try(:value) + end + def get_add_menu @add = [] Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| diff --git a/app/controllers/site_pages_controller.rb b/app/controllers/site_pages_controller.rb new file mode 100644 index 000000000..903e037db --- /dev/null +++ b/app/controllers/site_pages_controller.rb @@ -0,0 +1,94 @@ +class SitePagesController < ApplicationController + before_action :require_login, except: [:softbot_build, :themes] + before_action :require_profile_completed, only: [:create] + before_action :load_project, except: [:softbot_build, :index, :themes] + before_action :authenticate_user!, except: [:softbot_build, :index, :themes, :show] + before_action :authenticate_member!, only: [:show] + + def index + pages = PageQuery.call(params,current_user) + @total_count = pages.size + @pages = paginate(pages) + end + + def show + @page = Page.find_by(project_id: @project.id) + return render_ok({data:nil}) unless @page.present? + end + + def create + return normal_status(-1, "你还未开通Page服务,无法进行部署") unless current_user.website_permission + return normal_status(-1, "你已使用了 #{params[:identifier]} 作为page标识") if Page.exists?(identifier: params[:identifier], user: current_user) + return normal_status(-1, "该仓库已开通Page服务") if Page.exists?(project: @project) + @page = Page.new(create_params) + @page.user = current_user + @page.project = @project + @page.save + end + + def build + return normal_status(-1, "你还未开通Page服务,无法进行部署") unless current_user.website_permission + return normal_status(-1, "该仓库还未开通Page服务,无法进行部署") unless Page.exists?(project: @project) + @page = Page.find params[:id] + return normal_status(-1, @page.state_description) unless @page.state + response_str = @page.deploy_page(params[:branch]) + data = JSON.parse(response_str)["result"] || data = JSON.parse(response_str)["error"] + if data.to_s.include?("部署成功") + @page.update(last_build_at: Time.now, build_state: true, last_build_info: data) + else + @page.update(build_state:false, last_build_info: data) + end + render_ok({data: data.nil? ? nil : data.split("\n") }) + end + + def softbot_build + branch = params[:ref].split("/").last + user = User.find_by_login params[:repository][:owner][:login] + return normal_status(-1, "你还未开通Page服务,无法进行部署") unless user.website_permission + + project = Project.where(identifier: params[:repository][:name],user_id: user.id) + return normal_status(-1, "你没有权限操作") if project.owner?(user) + return normal_status(-1, "该仓库还未开通Page服务,无法进行部署") if Page.exists?(user: user, project: project) + + @page = Page.find_by(user: user, project: project) + response_str = @page.deploy_page(branch) + data = JSON.parse(response_str)["result"] + if data.nil? + data = JSON.parse(response_str)["error"] + end + + if data.include?("部署成功") + @page.update(last_build_at: Time.now, build_state: true, last_build_info: data) + else + @page.update(build_state:false, last_build_info: data) + end + render_ok + end + + def themes + # data = YAML.load_file(Rails.root.join('config/admins', 'page_themes.yml')) + # render_ok({themes:data[theme_params.downcase]}) + @themes = PageTheme.where(language_frame:theme_params).order(order_index: :asc) + end + + private + def authenticate_user! + unless @project.manager?(current_user) || current_user.admin? + return render_forbidden('你不是管理员,没有权限操作') + end + end + + def authenticate_member! + unless @project.member?(current_user) || current_user.admin? + return render_forbidden('你不是成员,没有权限操作') + end + end + + def theme_params + params[:language_frame] || "hugo" + end + + def create_params + params.permit(:identifier, :language_frame, :theme, :site_name) + end +end diff --git a/app/controllers/users/clas_controller.rb b/app/controllers/users/clas_controller.rb new file mode 100644 index 000000000..b1e09cacc --- /dev/null +++ b/app/controllers/users/clas_controller.rb @@ -0,0 +1,43 @@ +class Users::ClasController < Users::BaseController + before_action :require_login + before_action :private_user_resources! + def index + @user_clas = UserCla.where(user: current_user) + end + + def show + @user_cla = current_user.user_clas.find params[:id] + end + + def create + @user_cla = current_user.user_clas.find_by(cla_id: params[:cla_id]) + if @user_cla.nil? + ActiveRecord::Base.transaction do + Users::UserClaForm.new(user_cla_params).validate! + @user_cla = UserCla.build(user_cla_params, current_user.id) + + end + elsif @user_cla.state == "failed" + @user_cla.update_by_params(user_cla_params) + elsif @user_cla.state == "signed" + return render_error('协议生效中,请勿重复签署') + end + render_ok + rescue Exception => e + uid_logger_error(e.message) + tip_exception(e.message) + end + + def destroy + @user_cla = current_user.user_clas.find params[:id] + @user_cla.update_attributes(state: 2) + render_ok + end + + private + + def user_cla_params + params.permit(:email, :real_name, :cla_id) + end + +end diff --git a/app/controllers/users/project_trends_controller.rb b/app/controllers/users/project_trends_controller.rb index 9edd56f18..5c636f63b 100644 --- a/app/controllers/users/project_trends_controller.rb +++ b/app/controllers/users/project_trends_controller.rb @@ -6,6 +6,7 @@ class Users::ProjectTrendsController < Users::BaseController else @project_trends = observed_user.project_trends end + @project_trends = @project_trends.left_joins(:project).where("projects.is_public = TRUE") @project_trends = kaminari_paginate(@project_trends.includes(:trend, :project).order(created_at: :desc)) end end \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6cf505a6d..34d617f19 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -212,6 +212,10 @@ class UsersController < ApplicationController def update return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id]) return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id) + if user_params[:nickname].present? + keywords = user_params[:nickname].to_s.each_char.select { |c| c.bytes.first < 240 }.join('') + return normal_status(-1, "昵称中包含关键词:#{keywords},请重新命名") if ReversedKeyword.check_exists?(keywords) + end Util.write_file(@image, avatar_path(@user)) if user_params[:image].present? @user.attributes = user_params.except(:image) unless @user.save @@ -759,10 +763,11 @@ class UsersController < ApplicationController password = "12345678" # 没有用户时,新建用户并登录 - user = User.where("login = ? or phone = ? or mail = ? ", "#{login}", phone, email).first + user = phone.present? ? User.find_by(phone: phone) : nil + user = User.where("login = ? or phone = ? or mail = ? ", "#{login}", phone, email).first if user.nil? if user.present? # 手机号先记录,后续用 - user.update_column(:phone, "#{phone}") if phone.present? + user.update_column(:phone, "#{phone}") if phone.present? && user.phone.blank? else ActiveRecord::Base.transaction do email = "#{login}@gitlink.org.cn" if email.blank? diff --git a/app/forms/organizations/create_cla_form.rb b/app/forms/organizations/create_cla_form.rb new file mode 100644 index 000000000..ce20a23ce --- /dev/null +++ b/app/forms/organizations/create_cla_form.rb @@ -0,0 +1,6 @@ +class Organizations::CreateClaForm < BaseForm + KEY_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 + attr_accessor :name, :key, :content, :pr_need + validates :name , :key, presence: true + validates :key, format: { with: KEY_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } +end \ No newline at end of file diff --git a/app/forms/projects/migrate_form.rb b/app/forms/projects/migrate_form.rb index 12a4ee617..98ebbc7ac 100644 --- a/app/forms/projects/migrate_form.rb +++ b/app/forms/projects/migrate_form.rb @@ -1,5 +1,5 @@ class Projects::MigrateForm < BaseForm - attr_accessor :user_id, :name, :repository_name, :project_category_id, :description, + attr_accessor :user_id, :name, :repository_name, :project_category_id, :description, :auth_token, :project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner validates :user_id, :name, :repository_name, :clone_addr, presence: true diff --git a/app/forms/register/remote_form.rb b/app/forms/register/remote_form.rb index 59a5fbc82..c3eda4358 100644 --- a/app/forms/register/remote_form.rb +++ b/app/forms/register/remote_form.rb @@ -1,15 +1,16 @@ module Register class RemoteForm < Register::BaseForm # login 登陆方式,支持邮箱、登陆、手机号等 - attr_accessor :username, :email, :password, :platform + attr_accessor :username, :email, :password, :platform, :user_id validates :username, :email, :password, presence: true validate :check! def check! - Rails.logger.info "Register::RemoteForm params: username: #{username}; email: #{email}; password: #{password}; platform: #{platform}" - check_login(username) - check_mail(email) + user = User.find_by(id: user_id) + Rails.logger.info "Register::RemoteForm params: id: #{user&.id}; username: #{username}; email: #{email}; password: #{password}; platform: #{platform}" + check_login(username, user) + check_mail(email,user) check_password(password) end end diff --git a/app/forms/users/user_cla_form.rb b/app/forms/users/user_cla_form.rb new file mode 100644 index 000000000..24f615591 --- /dev/null +++ b/app/forms/users/user_cla_form.rb @@ -0,0 +1,6 @@ +class Users::UserClaForm + include ActiveModel::Model + attr_accessor :email, :real_name, :cla_id + validates :email, presence: true, format: { with: CustomRegexp::EMAIL } + end + \ No newline at end of file diff --git a/app/helpers/admins/glcc_pr_check_helper.rb b/app/helpers/admins/glcc_pr_check_helper.rb new file mode 100644 index 000000000..9934b83bf --- /dev/null +++ b/app/helpers/admins/glcc_pr_check_helper.rb @@ -0,0 +1,2 @@ +module Admins::GlccPrCheckHelper +end diff --git a/app/helpers/admins/identity_verifications_helper.rb b/app/helpers/admins/identity_verifications_helper.rb new file mode 100644 index 000000000..c44651a7f --- /dev/null +++ b/app/helpers/admins/identity_verifications_helper.rb @@ -0,0 +1,2 @@ +module Admins::IdentityVerificationsHelper +end diff --git a/app/helpers/admins/page_themes_helper.rb b/app/helpers/admins/page_themes_helper.rb new file mode 100644 index 000000000..721d9b78c --- /dev/null +++ b/app/helpers/admins/page_themes_helper.rb @@ -0,0 +1,2 @@ +module Admins::PageThemesHelper +end diff --git a/app/helpers/admins/site_pages_helper.rb b/app/helpers/admins/site_pages_helper.rb new file mode 100644 index 000000000..d21cdefb9 --- /dev/null +++ b/app/helpers/admins/site_pages_helper.rb @@ -0,0 +1,2 @@ +module Admins::SitePagesHelper +end diff --git a/app/helpers/identity_verifications_helper.rb b/app/helpers/identity_verifications_helper.rb new file mode 100644 index 000000000..acd433185 --- /dev/null +++ b/app/helpers/identity_verifications_helper.rb @@ -0,0 +1,2 @@ +module IdentityVerificationsHelper +end diff --git a/app/helpers/organizations/clas_helper.rb b/app/helpers/organizations/clas_helper.rb new file mode 100644 index 000000000..38c1531c3 --- /dev/null +++ b/app/helpers/organizations/clas_helper.rb @@ -0,0 +1,2 @@ +module Organizations::ClasHelper +end diff --git a/app/helpers/pages_helper.rb b/app/helpers/pages_helper.rb new file mode 100644 index 000000000..2c057fd05 --- /dev/null +++ b/app/helpers/pages_helper.rb @@ -0,0 +1,2 @@ +module PagesHelper +end diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index c9be515d2..f364c11ff 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -16,7 +16,11 @@ module RepositoriesHelper def image_type?(str) default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd) - default_type.include?(str&.downcase) + default_type.include?(str.to_s.gsub("\r", "").downcase) + end + + def is_text_file?(entry) + entry['is_text_file'] end def is_readme?(type, str) @@ -36,18 +40,26 @@ module RepositoriesHelper end def render_cache_commit_author(author_json) + user = nil if author_json["name"].present? && author_json["email"].present? - return find_user_in_redis_cache(author_json['name'], author_json['email']) + user = find_user_in_redis_cache(author_json['name'], author_json['email']) end if author_json["Name"].present? && author_json["Email"].present? - return find_user_in_redis_cache(author_json['Name'], author_json['Email']) + user = find_user_in_redis_cache(author_json['Name'], author_json['Email']) end + if user.blank? && author_json["email"].present? + user = User.find_by(mail: author_json["email"]) + end + if user.blank? && author_json["Email"].present? + user = User.find_by(mail: author_json["Email"]) + end + user end def readme_render_decode64_content(str, owner, repo, ref, path) return nil if str.blank? begin - content = Base64.decode64(str).force_encoding('UTF-8') + content = Base64.decode64(content).force_encoding('UTF-8').valid_encoding? ? Base64.decode64(str).force_encoding('UTF-8') : Base64.decode64(str).force_encoding("GBK").encode("UTF-8") c_regex = /\!\[.*?\]\((.*?)\)/ src_regex = /src=\"(.*?)\"/ @@ -107,19 +119,30 @@ module RepositoriesHelper def new_readme_render_decode64_content(str, owner, repo, ref, readme_path, readme_name) file_path = readme_path.include?('/') ? readme_path.gsub("/#{readme_name}", '') : readme_path.gsub("#{readme_name}", '') return nil if str.blank? - content = Base64.decode64(str).force_encoding('UTF-8') + content = Base64.decode64(str).force_encoding('UTF-8').valid_encoding? ? Base64.decode64(str).force_encoding('UTF-8') : Base64.decode64(str).force_encoding("GBK").encode("UTF-8") # s_regex = /\s\!\[.*?\]\((.*?)\)\s/ s_regex_c = /`{1,2}[^`](.*?)`{1,2}/ s_regex = /```([\s\S]*?)```[\s]?/ s_regex_1 = /\[.*?\]\((.*?)\)/ + # 变量图片相对路径 + s_regex_2 = /\[.*?\]:(.*?)\n/ src_regex = /src=\"(.*?)\"/ src_regex_1 = /src=\'(.*?)\'/ + src_regex_2 = /src = (.*?) / + src_regex_3 = /src= (.*?) / + src_regex_4 = /src =(.*?) / + src_regex_5 = /src =(.*?) / ss_c = content.to_s.scan(s_regex_c) ss = content.to_s.scan(s_regex) ss_1 = content.to_s.scan(s_regex_1) + ss_2 = content.to_s.scan(s_regex_2) ss_src = content.to_s.scan(src_regex) ss_src_1 = content.to_s.scan(src_regex_1) - total_sources = {ss_c: ss_c,ss: ss, ss_1: ss_1, ss_src: ss_src, ss_src_1: ss_src_1} + ss_src_2 = content.to_s.scan(src_regex_2) + ss_src_3 = content.to_s.scan(src_regex_3) + ss_src_4 = content.to_s.scan(src_regex_4) + ss_src_5 = content.to_s.scan(src_regex_5) + total_sources = {ss_c: ss_c,ss: ss, ss_1: ss_1, ss_2: ss_2, ss_src: ss_src, ss_src_1: ss_src_1, ss_src_2: ss_src_2, ss_src_3: ss_src_3, ss_src_4: ss_src_4, ss_src_5: ss_src_5} # total_sources.uniq! total_sources.except(:ss, :ss_c).each do |k, sources| sources.each do |s| @@ -128,17 +151,29 @@ module RepositoriesHelper # 链接直接跳过不做替换 next if s_content.starts_with?('http://') || s_content.starts_with?('https://') || s_content.starts_with?('mailto:') || s_content.blank? ext = File.extname(s_content)[1..-1] + ext = ext.split("?")[0] if ext.include?("?") if (image_type?(ext) || download_type(ext)) && !ext.blank? s_content = File.expand_path(s_content, file_path) s_content = s_content.split("#{Rails.root}/")[1] # content = content.gsub(s[0], "/#{s_content}") - s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw/#{s_content}?ref=#{ref}"].join - case k.to_s + join_xxx = s_content.include?("?") ? "&" : "?" + s_content = [base_url, "/api/#{owner&.login}/#{repo.identifier}/raw/#{s_content}#{join_xxx}ref=#{ref}"].join + case k.to_s when 'ss_src' content = content.gsub("src=\"#{s[0]}\"", "src=\"#{s_content}\"") when 'ss_src_1' content = content.gsub("src=\'#{s[0]}\'", "src=\'#{s_content}\'") - else + when 'ss_src_2' + content = content.gsub("src = #{s[0]}", "src=\'#{s_content}\'") + when 'ss_src_3' + content = content.gsub("src= #{s[0]}", "src=\'#{s_content}\'") + when 'ss_src_4' + content = content.gsub("src =#{s[0]}", "src=\'#{s_content}\'") + when 'ss_src_5' + content = content.gsub("src=#{s[0]}", "src=\'#{s_content}\'") + when 'ss_2' + content = content.gsub(/]:#{s[0]}/, "]: #{s_content.to_s.gsub(" ","").gsub("\r", "")}") + else content = content.gsub("(#{s[0]})", "(#{s_content})") end else @@ -150,7 +185,9 @@ module RepositoriesHelper content = content.gsub("src=\"#{s[0]}\"", "src=\"/#{s_content}\"") when 'ss_src_1' content = content.gsub("src=\'#{s[0]}\'", "src=\'/#{s_content}\'") - else + when 'ss_2' + content = content.gsub(/]:#{s[0]}/, "]: /#{s_content.to_s.gsub(" ","").gsub("\r", "")}") + else content = content.gsub("(#{s[0]})", "(/#{s_content})") end end @@ -168,9 +205,10 @@ module RepositoriesHelper after_ss_c_souces.each_with_index do |s, index| content = content.gsub("#{s[0]}","#{total_sources[:ss_c][index][0]}") end - return content - rescue + rescue Exception => e + Rails.logger.error("===================#{readme_path}:#{readme_name}:error:#{e}") + # e.backtrace.each { |msg| Rails.logger.error(msg) } return str end @@ -186,8 +224,7 @@ module RepositoriesHelper def readme_decode64_content(entry, owner, repo, ref, path=nil) Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") - content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] - # Rails.logger.info("content===#{content}") + content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] # readme_render_decode64_content(content, owner, repo, ref) new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name']) end @@ -195,10 +232,12 @@ module RepositoriesHelper def decode64_content(entry, owner, repo, ref, path=nil) if is_readme?(entry['type'], entry['name']) Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") - content = Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] + content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] # Rails.logger.info("content===#{content}") - # readme_render_decode64_content(content, owner, repo, ref) + return Base64.decode64(content).force_encoding("GBK").encode("UTF-8") unless Base64.decode64(content).force_encoding('UTF-8').valid_encoding? return Base64.decode64(content).force_encoding('UTF-8') + elsif entry['is_text_file'] == true + return render_decode64_content(entry['content']) else file_type = File.extname(entry['name'].to_s)[1..-1] if image_type?(file_type) diff --git a/app/helpers/users/clas_helper.rb b/app/helpers/users/clas_helper.rb new file mode 100644 index 000000000..55e326d0d --- /dev/null +++ b/app/helpers/users/clas_helper.rb @@ -0,0 +1,2 @@ +module Users::ClasHelper +end diff --git a/app/interactors/gitea/delete_file_interactor.rb b/app/interactors/gitea/delete_file_interactor.rb index 103df6cd4..03ddf4230 100644 --- a/app/interactors/gitea/delete_file_interactor.rb +++ b/app/interactors/gitea/delete_file_interactor.rb @@ -42,6 +42,9 @@ module Gitea def render_result(response) if response.status == 200 @result = JSON.parse(response.body) + else + Rails.logger.error("Gitea::Repository::Entries::DeleteService error[#{response.status}]======#{response.body}") + @error = "删除失败,请确认该分支是否是保护分支。" end end diff --git a/app/interactors/gitea/update_file_interactor.rb b/app/interactors/gitea/update_file_interactor.rb index 38cfd98a8..1b729e2c8 100644 --- a/app/interactors/gitea/update_file_interactor.rb +++ b/app/interactors/gitea/update_file_interactor.rb @@ -42,6 +42,9 @@ module Gitea def render_result(response) if response.status == 200 @result = JSON.parse(response.body) + else + Rails.logger.error("Gitea::Repository::Entries::UpdateService error[#{response.status}]======#{response.body}") + @error = "更新失败,请确认该分支是否是保护分支。" end end diff --git a/app/jobs/migrate_remote_repository_job.rb b/app/jobs/migrate_remote_repository_job.rb index 0e30bfefe..2493bff01 100644 --- a/app/jobs/migrate_remote_repository_job.rb +++ b/app/jobs/migrate_remote_repository_job.rb @@ -15,11 +15,13 @@ class MigrateRemoteRepositoryJob < ApplicationJob ## open jianmu devops project_id = repo&.project&.id puts "############ mirror project_id,user_id: #{project_id},#{user_id} ############" - # OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(project_id, user_id) if project_id.present? && user_id.present? + OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(project_id, user_id) if project_id.present? && user_id.present? + UpdateProjectTopicJob.set(wait: 1.seconds).perform_later(project_id) if project_id.present? puts "############ mirror status: #{repo.mirror.status} ############" else repo&.mirror&.failed! end - BroadcastMirrorRepoMsgJob.perform_later(repo.id) unless repo&.mirror.waiting? + # UpdateProjectTopicJob 中语言要延迟1S才能获取 + BroadcastMirrorRepoMsgJob.set(wait: 1.seconds).perform_later(repo.id) unless repo&.mirror.waiting? end end diff --git a/app/jobs/send_template_message_job.rb b/app/jobs/send_template_message_job.rb index 05572d451..1df1d8c7d 100644 --- a/app/jobs/send_template_message_job.rb +++ b/app/jobs/send_template_message_job.rb @@ -8,7 +8,7 @@ class SendTemplateMessageJob < ApplicationJob receivers_id, template_id, props = args[0], args[1], args[2] template = MessageTemplate.find_by_id(template_id) return unless template.present? - receivers = User.where(id: receivers_id).or(User.where(mail: receivers_id)) + receivers = User.where("id in(?)", receivers_id).or(User.where(mail: receivers_id)) not_exists_receivers = receivers_id - receivers.pluck(:id) - receivers.pluck(:mail) receivers_string, content, notification_url = MessageTemplate::CustomTip.get_message_content(receivers, template, props) Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {receivers_id: receivers_id, template_id: template_id, props: props}) diff --git a/app/jobs/sync_repo_update_time_job.rb b/app/jobs/sync_repo_update_time_job.rb index 4391f2c13..8692391a8 100644 --- a/app/jobs/sync_repo_update_time_job.rb +++ b/app/jobs/sync_repo_update_time_job.rb @@ -3,9 +3,9 @@ class SyncRepoUpdateTimeJob < ApplicationJob def perform(*args) # Do something later - Project.forge.find_each do |project| - update_repo_time!(project) - end + # Project.forge.find_each do |project| + # update_repo_time!(project) + # end end private diff --git a/app/jobs/touch_webhook_job.rb b/app/jobs/touch_webhook_job.rb index 0a8c03e9f..514fa6950 100644 --- a/app/jobs/touch_webhook_job.rb +++ b/app/jobs/touch_webhook_job.rb @@ -49,9 +49,9 @@ class TouchWebhookJob < ApplicationJob when 'IssueComment' issue_id, sender_id, comment_id, action_type, comment_json = args[0], args[1], args[2], args[3], args[4] issue = Issue.find_by_id issue_id - comment = issue.comment_journals.find_by_id comment_id sender = User.find_by_id sender_id - return if issue.nil? || sender.nil? + return if issue.nil? || sender.nil? + comment = issue.comment_journals.find_by_id comment_id return if action_type == 'edited' && comment_json.blank? issue.project.webhooks.each do |webhook| @@ -63,10 +63,10 @@ class TouchWebhookJob < ApplicationJob when 'PullRequestComment' issue_id, sender_id, comment_id, action_type, comment_json = args[0], args[1], args[2], args[3], args[4] issue = Issue.find_by_id(issue_id) - comment = issue.comment_journals.find_by_id comment_id sender = User.find_by_id sender_id pull = issue.try(:pull_request) - return if pull.nil? || sender.nil? + return if issue.nil? || pull.nil? || sender.nil? + comment = issue.comment_journals.find_by_id comment_id return if action_type == 'edited' && comment_json.blank? pull.project.webhooks.each do |webhook| diff --git a/app/jobs/update_project_topic_job.rb b/app/jobs/update_project_topic_job.rb new file mode 100644 index 000000000..52341d672 --- /dev/null +++ b/app/jobs/update_project_topic_job.rb @@ -0,0 +1,33 @@ +class UpdateProjectTopicJob < ApplicationJob + include ProjectsHelper + + queue_as :message + + def perform(project_id) + project = Project.find_by(id: project_id) + return if project.blank? + begin + languages = $gitea_client.get_repos_languages_by_owner_repo(project.owner.login, project.identifier) + puts "#{project.owner.login}/#{project.identifier} get_repos_languages:#{languages}" + topic_count = 0 + if project.project_category_id.present? + project_topic = ProjectTopic.find_or_create_by!(name: project.project_category.name.downcase) + project_topic_ralate = project_topic.project_topic_ralates.find_or_create_by!(project_id: project.id) + if project_topic.present? && project_topic_ralate.present? + topic_count +=1 + end + end + languages.each do |k, _| + next if topic_count >= 3 + project_topic = ProjectTopic.find_or_create_by!(name: k.downcase) + project_topic_ralate = project_topic.project_topic_ralates.find_or_create_by!(project_id: project.id) + if project_topic.present? && project_topic_ralate.present? + topic_count +=1 + end + end + rescue => e + puts "get_repos_languages: error:#{e.message}" + end + end + +end \ No newline at end of file diff --git a/app/libs/getway.rb b/app/libs/getway.rb new file mode 100644 index 000000000..0b876b839 --- /dev/null +++ b/app/libs/getway.rb @@ -0,0 +1,20 @@ +module Getway + class << self + def getway_config + getway_config = {} + + begin + config = Rails.application.config_for(:configuration).symbolize_keys! + getway_config = config[:getway].symbolize_keys! + raise 'getway config missing' if getway_config.blank? + rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] getway config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + getway_config = {} + end + getway_config + end + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 28bbccf63..a99948879 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -30,4 +30,11 @@ class UserMailer < ApplicationMailer def feedback_email(mail, title, content) mail(to: mail, subject: title, content_type: "text/html", body: content) end + + def glcc_pr_check_email(mail, title, name, content) + @content = content + @name = name + mail(to: mail, subject: title) + end + end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 0cbf6fb0f..f79aca153 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,41 +1,44 @@ -# == Schema Information -# -# Table name: attachments -# -# id :integer not null, primary key -# container_id :integer -# container_type :string(30) -# filename :string(255) default(""), not null -# disk_filename :string(255) default(""), not null -# filesize :integer default("0"), not null -# content_type :string(255) default("") -# digest :string(60) default(""), not null -# downloads :integer default("0"), not null -# author_id :integer default("0"), not null -# created_on :datetime -# description :text(65535) -# disk_directory :string(255) -# attachtype :integer default("1") -# is_public :integer default("1") -# copy_from :string(255) -# quotes :integer default("0") -# is_publish :integer default("1") -# publish_time :datetime -# resource_bank_id :integer -# unified_setting :boolean default("1") -# cloud_url :string(255) default("") -# course_second_category_id :integer default("0") -# delay_publish :boolean default("0") -# link :string(255) -# clone_id :integer -# -# Indexes -# -# index_attachments_on_author_id (author_id) -# index_attachments_on_clone_id (clone_id) -# index_attachments_on_container_id_and_container_type (container_id,container_type) -# index_attachments_on_created_on (created_on) -# +# == Schema Information +# +# Table name: attachments +# +# id :integer not null, primary key +# container_id :integer +# container_type :string(30) +# filename :string(255) default(""), not null +# disk_filename :string(255) default(""), not null +# filesize :integer default("0"), not null +# content_type :string(255) default("") +# digest :string(60) default(""), not null +# downloads :integer default("0"), not null +# author_id :integer default("0"), not null +# created_on :datetime +# description :text(65535) +# disk_directory :string(255) +# attachtype :integer default("1") +# is_public :integer default("1") +# copy_from :integer +# quotes :integer default("0") +# is_publish :integer default("1") +# publish_time :datetime +# resource_bank_id :integer +# unified_setting :boolean default("1") +# cloud_url :string(255) default("") +# course_second_category_id :integer default("0") +# delay_publish :boolean default("0") +# memo_image :boolean default("0") +# extra_type :integer default("0") +# +# Indexes +# +# index_attachments_on_author_id (author_id) +# index_attachments_on_container_id_and_container_type (container_id,container_type) +# index_attachments_on_course_second_category_id (course_second_category_id) +# index_attachments_on_created_on (created_on) +# index_attachments_on_is_public (is_public) +# index_attachments_on_quotes (quotes) +# + diff --git a/app/models/bot.rb b/app/models/bot.rb index 13ac70a78..e7a14d009 100644 --- a/app/models/bot.rb +++ b/app/models/bot.rb @@ -2,23 +2,24 @@ # # Table name: bot # -# id :integer not null, primary key -# bot_name :string(255) -# bot_des :text(4294967295) -# webhook :string(255) -# is_public :integer -# logo :string(255) -# state :integer -# client_id :string(255) -# client_secret :string(255) -# web_url :string(255) -# category :string(255) -# install_num :integer default("0") -# update_time :datetime not null -# create_time :datetime not null -# private_key :text(65535) -# uid :integer -# owner_id :integer +# id :integer not null, primary key +# bot_name :string(255) not null +# bot_des :text(4294967295) +# webhook :string(255) not null +# is_public :integer +# logo :string(255) +# state :integer +# client_id :string(255) +# client_secret :string(255) +# web_url :string(255) +# category :string(255) +# install_num :integer default("0") +# update_time :datetime not null +# create_time :datetime not null +# uid :integer +# owner_id :integer +# private_key :text(65535) +# oauth_callback_url :string(255) not null # # Indexes # diff --git a/app/models/bot_install.rb b/app/models/bot_install.rb index d5283c131..57e5a750b 100644 --- a/app/models/bot_install.rb +++ b/app/models/bot_install.rb @@ -2,13 +2,18 @@ # # Table name: install_bot # -# id :integer not null, primary key -# bot_id :integer not null -# installer_id :integer not null -# store_id :integer not null -# state :integer not null -# create_time :datetime not null -# update_time :datetime not null +# id :integer not null, primary key +# bot_id :integer not null +# installer_id :integer not null +# store_id :integer not null +# state :integer not null +# create_time :datetime not null +# update_time :datetime not null +# installer_login :string(255) not null +# store_repo :string(255) not null +# webhook_id :integer +# webhook_response_msg :text(65535) +# repo_owner :string(255) # # frozen_string_literal: true diff --git a/app/models/ci/user.rb b/app/models/ci/user.rb index e4a4d0623..aae6e601c 100644 --- a/app/models/ci/user.rb +++ b/app/models/ci/user.rb @@ -39,15 +39,17 @@ # business :boolean default("0") # profile_completed :boolean default("0") # laboratory_id :integer -# is_shixun_marker :boolean default("0") -# admin_visitable :boolean default("0") -# collaborator :boolean default("0") +# 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") -# gitea_token :string(255) -# platform :string(255) +# sign_cla :boolean default("0") +# enabling_cla :boolean default("0") +# id_card_verify :boolean default("0") +# website_permission :boolean default("0") # # Indexes # @@ -56,8 +58,7 @@ # index_users_on_homepage_teacher (homepage_teacher) # index_users_on_laboratory_id (laboratory_id) # index_users_on_login (login) UNIQUE -# index_users_on_mail (mail) UNIQUE -# index_users_on_phone (phone) UNIQUE +# index_users_on_mail (mail) # index_users_on_type (type) # diff --git a/app/models/cla.rb b/app/models/cla.rb new file mode 100644 index 000000000..6bbfb6143 --- /dev/null +++ b/app/models/cla.rb @@ -0,0 +1,46 @@ +# == Schema Information +# +# Table name: clas +# +# id :integer not null, primary key +# name :string(255) not null +# key :string(255) not null +# content :text(65535) +# organization_id :integer not null +# pr_need :boolean default("0") +# count :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_clas_on_key (key) +# index_clas_on_organization_id (organization_id) +# + +class Cla < ApplicationRecord + has_many :user_clas, :dependent => :destroy + has_many :users, through: :user_clas + belongs_to :organization + + def to_param + self.key.parameterize + end + + def self.build(params,org_id) + self.create!(organization_id: org_id, + name: params[:name], + key: params[:key], + content: params[:content], + pr_need: params[:pr_need] + ) + end + + def valid_sign(user_id) + user_clas.where(user_id: user_id, state:1).present? + end + def fresh_count + number = self.user_clas.where(state: 1).count + update(count: number) + end +end diff --git a/app/models/commit_log.rb b/app/models/commit_log.rb index def2846fa..d351e6f48 100644 --- a/app/models/commit_log.rb +++ b/app/models/commit_log.rb @@ -1,3 +1,26 @@ +# == Schema Information +# +# Table name: commit_logs +# +# id :integer not null, primary key +# user_id :integer +# project_id :integer +# repository_id :integer +# name :string(255) +# full_name :string(255) +# commit_id :string(255) +# ref :string(255) +# message :text(65535) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_commit_logs_on_commit_id (commit_id) +# index_commit_logs_on_project_id (project_id) +# index_commit_logs_on_user_id (user_id) +# + class CommitLog < ApplicationRecord belongs_to :user belongs_to :project diff --git a/app/models/concerns/project_operable.rb b/app/models/concerns/project_operable.rb index 4fee9ea33..9a5efd129 100644 --- a/app/models/concerns/project_operable.rb +++ b/app/models/concerns/project_operable.rb @@ -200,7 +200,7 @@ module ProjectOperable if owner.is_a?(User) managers.exists?(user_id: user.id) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) elsif owner.is_a?(Organization) - managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || (owner.is_only_admin?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) + managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || (owner.is_admin?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) else false end @@ -212,7 +212,7 @@ module ProjectOperable if owner.is_a?(User) developers.exists?(user_id: user.id) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) elsif owner.is_a?(Organization) - developers.exists?(user_id: user.id) || (owner.is_only_write?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) + developers.exists?(user_id: user.id) || (owner.is_write?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0) || (user.platform == "bot" && BotInstall.joins(:bot).where(bot: { uid: user.id }).where(store_id: self.id).exists?) else false end diff --git a/app/models/edu_setting.rb b/app/models/edu_setting.rb index 22575ff15..f4a89c09b 100644 --- a/app/models/edu_setting.rb +++ b/app/models/edu_setting.rb @@ -1,18 +1,19 @@ -# == Schema Information -# -# Table name: edu_settings -# -# id :integer not null, primary key -# name :string(255) -# value :string(255) -# created_at :datetime not null -# updated_at :datetime not null -# description :string(255) -# -# Indexes -# -# index_edu_settings_on_name (name) UNIQUE -# +# == Schema Information +# +# Table name: edu_settings +# +# id :integer not null, primary key +# name :string(255) +# value :string(255) +# created_at :datetime not null +# updated_at :datetime not null +# description :string(255) +# +# Indexes +# +# index_edu_settings_on_name (name) UNIQUE +# + class EduSetting < ApplicationRecord after_commit :expire_value_cache diff --git a/app/models/gitea/public_key.rb b/app/models/gitea/public_key.rb index bb2192358..a9962dc67 100644 --- a/app/models/gitea/public_key.rb +++ b/app/models/gitea/public_key.rb @@ -1,3 +1,25 @@ +# == Schema Information +# +# Table name: public_key +# +# id :integer not null, primary key +# owner_id :integer not null +# name :string(255) not null +# fingerprint :string(255) not null +# content :text(16777215) not null +# mode :integer default("2"), not null +# type :integer default("1"), not null +# login_source_id :integer default("0"), not null +# created_unix :integer +# updated_unix :integer +# verified :boolean default("0"), not null +# +# Indexes +# +# IDX_public_key_fingerprint (fingerprint) +# IDX_public_key_owner_id (owner_id) +# + class Gitea::PublicKey < Gitea::Base self.inheritance_column = nil # FIX The single-table inheritance mechanism failed # establish_connection :gitea_db diff --git a/app/models/gitea/pull.rb b/app/models/gitea/pull.rb index 7adb8c366..70e61f5fa 100644 --- a/app/models/gitea/pull.rb +++ b/app/models/gitea/pull.rb @@ -16,10 +16,12 @@ # head_branch :string(255) # base_branch :string(255) # merge_base :string(40) +# allow_maintainer_edit :boolean default("0"), not null # has_merged :boolean # merged_commit_id :string(40) # merger_id :integer # merged_unix :integer +# flow :integer default("0"), not null # # Indexes # diff --git a/app/models/gitea/webhook.rb b/app/models/gitea/webhook.rb index f60f56788..ec1c836c4 100644 --- a/app/models/gitea/webhook.rb +++ b/app/models/gitea/webhook.rb @@ -1,3 +1,32 @@ +# == Schema Information +# +# Table name: webhook +# +# id :integer not null, primary key +# repo_id :integer +# org_id :integer +# is_system_webhook :boolean +# url :text(65535) +# http_method :string(255) +# content_type :integer +# secret :text(65535) +# events :text(65535) +# is_active :boolean +# type :string(16) +# meta :text(65535) +# last_status :integer +# created_unix :integer +# updated_unix :integer +# +# Indexes +# +# IDX_webhook_created_unix (created_unix) +# IDX_webhook_is_active (is_active) +# IDX_webhook_org_id (org_id) +# IDX_webhook_repo_id (repo_id) +# IDX_webhook_updated_unix (updated_unix) +# + class Gitea::Webhook < Gitea::Base serialize :events, JSON self.inheritance_column = nil @@ -10,4 +39,4 @@ class Gitea::Webhook < Gitea::Base enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} enum last_status: {waiting: 0, succeed: 1, fail: 2} enum content_type: {json: 1, form: 2} -end \ No newline at end of file +end diff --git a/app/models/gitea/webhook_task.rb b/app/models/gitea/webhook_task.rb index 7e9bc68a7..b612816ba 100644 --- a/app/models/gitea/webhook_task.rb +++ b/app/models/gitea/webhook_task.rb @@ -1,3 +1,19 @@ +# == Schema Information +# +# Table name: hook_task +# +# id :integer not null, primary key +# hook_id :integer +# uuid :string(255) +# payload_content :text(4294967295) +# event_type :string(255) +# is_delivered :boolean +# delivered :integer +# is_succeed :boolean +# request_content :text(4294967295) +# response_content :text(4294967295) +# + class Gitea::WebhookTask < Gitea::Base serialize :payload_content, JSON serialize :request_content, JSON @@ -11,4 +27,4 @@ class Gitea::WebhookTask < Gitea::Base enum type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9} -end \ No newline at end of file +end diff --git a/app/models/glcc_medium_term_examine_material.rb b/app/models/glcc_medium_term_examine_material.rb new file mode 100644 index 000000000..0e22690c8 --- /dev/null +++ b/app/models/glcc_medium_term_examine_material.rb @@ -0,0 +1,103 @@ +# == Schema Information +# +# Table name: glcc_medium_term_examine_material +# +# id :integer not null, primary key +# student_reg_id :integer not null +# task_id :integer not null +# defence_video_url :string(1000) not null +# code_or_pr_url :string(1000) +# PPT_attachment_id :integer not null +# term :integer +# created_on :datetime +# updated_on :datetime +# is_delete :boolean default("0"), not null +# round :integer default("1"), not null +# + +class GlccMediumTermExamineMaterial < ActiveRecord::Base + self.table_name = "glcc_medium_term_examine_material" + belongs_to :glcc_student, :class_name => :GlccRegistrationStudent, :foreign_key => "student_reg_id" + belongs_to :task, :class_name => :GlccRegistrationTask, :foreign_key => "task_id" + + def check_pr_url + state = [] + # code_or_pr_url = "https://www.gitlink.org.cn/Gitlink/forgeplus/pulls/337" + url_array = code_or_pr_url.split("/") + gitlink_index = url_array.index("www.gitlink.org.cn") || url_array.index("gitlink.org.cn") || url_array.index("testforgeplus.trustie.net") + pull_index = url_array.index("pulls") + + #发送没有在gitlink上提交PR的邮件 + unless gitlink_index.present? + state << 1 + end + + # 输入的地址有问题邮件内容 + unless pull_index == 5 + state << 2 + end + user = Owner.find_by(login: url_array[3]) + project = Project.find_by(identifier: url_array[4], user_id:user.try(:id)) + pr = PullRequest.where(project:project, gitea_number:url_array[6]) + + unless pr.present? + state << 3 + end + if white_list #特殊处理 白名单考核不处理 + state = [] + end + state + end + + + def white_list + # 全局设置白名单 key + key = "glcc_white_task_#{self.created_on.year}" + white_task = EduSetting.find_by_name(key) + if white_task + task_ids = white_task.value.split(",") + task_ids.map(&:to_i).include?(self.task_id) + else + false + end + end + + def send_mail + gcs = glcc_student + mail = gcs.mail + return if mail.nil? || code_or_pr_url.nil? + + state = check_pr_url + return unless state.present? + title = "#{self.created_on.year}年GitLink确实开源GLCC开源夏令营#{term == 1 ? "中期考核" : "结项考核"}提醒" + content = gennerate_content(state) + UserMailer.glcc_pr_check_email(mail,title, gcs.student_name, content).deliver_now + end + + def state_to_html + gcs = glcc_student + mail = gcs.mail + return "数据异常,PR链接为空" if mail.nil? || code_or_pr_url.nil? + state = check_pr_url + gennerate_content(state) + end + + def gennerate_content(state) + content = "" + state.map{|e| + content = content + number_to_content(e) + } + content + end + + def number_to_content(num) + case num + when 1 + "
PR链接为非GitLink平台链接
" + when 2 + "PR链接为GitLink平台链接, 但非PR链接
" + when 3 + "PR链接中的PR不存在
" + end + end +end diff --git a/app/models/glcc_registration_student.rb b/app/models/glcc_registration_student.rb new file mode 100644 index 000000000..5dd988c95 --- /dev/null +++ b/app/models/glcc_registration_student.rb @@ -0,0 +1,24 @@ +# == Schema Information +# +# Table name: glcc_registration_student +# +# id :integer not null, primary key +# user_id :integer not null +# student_name :string(255) +# school :string(255) +# profession :string(255) +# location :string(255) +# grade :string(255) +# phone :string(255) +# mail :string(255) +# created_on :datetime +# is_delete :boolean default("0"), not null +# prove_attachment_id :integer +# cancel_count :integer default("0") +# round :integer default("1"), not null +# + +class GlccRegistrationStudent < ActiveRecord::Base + self.table_name = "glcc_registration_student" + has_many :examines, :class_name => :GlccMediumTermExamineMaterial, :foreign_key => "student_reg_id" +end diff --git a/app/models/glcc_registration_task.rb b/app/models/glcc_registration_task.rb new file mode 100644 index 000000000..da0d7cfd5 --- /dev/null +++ b/app/models/glcc_registration_task.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: glcc_registration_task +# +# id :integer not null, primary key +# reg_id :integer not null +# task_name :string(255) +# task_desc :text(16777215) +# task_difficulty :integer +# task_url :string(1000) +# task_reward :string(255) +# tutor_name :string(255) +# tutor_mail :string(255) +# tutor_phone :string(255) +# created_on :datetime +# is_delete :boolean default("0"), not null +# sort_no :integer default("0") +# locked :boolean default("0") +# round :integer default("1"), not null +# check_status :boolean default("0") +# +# Indexes +# +# idx_glcc_reg_id (reg_id) +# + +class GlccRegistrationTask < ActiveRecord::Base + self.table_name = "glcc_registration_task" + has_many :examines, :class_name => :GlccMediumTermExamineMaterial, :foreign_key => "task_id" +end diff --git a/app/models/help.rb b/app/models/help.rb index 5a4c480b4..8e0bcad78 100644 --- a/app/models/help.rb +++ b/app/models/help.rb @@ -9,7 +9,6 @@ # agreement :text(65535) # status :text(65535) # help_center :text(65535) -# join_us :text(65535) # class Help < ApplicationRecord diff --git a/app/models/identity_verification.rb b/app/models/identity_verification.rb new file mode 100644 index 000000000..3c8c88d9b --- /dev/null +++ b/app/models/identity_verification.rb @@ -0,0 +1,48 @@ +# == Schema Information +# +# Table name: identity_verifications +# +# id :integer not null, primary key +# user_id :integer not null +# number :string(255) not null +# name :string(255) not null +# card_front :integer +# card_back :integer +# hold_card_front :integer +# hold_card_back :integer +# state :integer default("0") +# description :string(255) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_identity_verifications_on_user_id (user_id) +# + +class IdentityVerification < ApplicationRecord + belongs_to :user + enum state: { "待审核": 0, "已通过": 1, "已拒绝": 2} + + after_save do + if state == "已通过" + user.update(id_card_verify: true, website_permission: true) + end + end + + def card_front_attachment + Attachment.find_by_id card_front + end + + def card_back_attachment + Attachment.find_by_id card_back + end + + def hold_card_front_attachment + Attachment.find_by_id hold_card_front + end + + def hold_card_back_attachment + Attachment.find_by_id hold_card_back + end +end diff --git a/app/models/import_repo.rb b/app/models/import_repo.rb index 8b53a7765..24c96a715 100644 --- a/app/models/import_repo.rb +++ b/app/models/import_repo.rb @@ -1,3 +1,26 @@ +# == Schema Information +# +# Table name: open_shixuns +# +# id :integer not null, primary key +# name :string(255) +# shixun_user_name :string(255) +# shixun_user_phone :string(255) +# shixun_user_mail :string(255) +# shixun_identifier :string(255) +# git_url :string(255) +# identifier :string(255) +# myshixun_git_url :string(255) +# myshixun_user_name :string(255) +# myshixun_user_phone :string(255) +# myshixun_user_mail :string(255) +# +# Indexes +# +# idx_email (myshixun_user_mail) +# idx_phone (myshixun_user_phone) +# + # for oauth2 application diff --git a/app/models/issue.rb b/app/models/issue.rb index e12f667db..eae5acf6f 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -5,7 +5,7 @@ # id :integer not null, primary key # tracker_id :integer not null # project_id :integer not null -# subject :string(255) default(""), not null +# subject :string(255) # description :text(4294967295) # due_date :date # category_id :integer @@ -33,6 +33,7 @@ # issue_classify :string(255) # ref_name :string(255) # branch_name :string(255) +# blockchain_token_num :integer # # Indexes # diff --git a/app/models/issue_participant.rb b/app/models/issue_participant.rb index fa7be6980..d756b28a2 100644 --- a/app/models/issue_participant.rb +++ b/app/models/issue_participant.rb @@ -1,3 +1,20 @@ +# == Schema Information +# +# Table name: issue_participants +# +# id :integer not null, primary key +# issue_id :integer +# participant_id :integer +# participant_type :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_issue_participants_on_issue_id (issue_id) +# index_issue_participants_on_participant_id (participant_id) +# + class IssueParticipant < ApplicationRecord belongs_to :issue diff --git a/app/models/issue_tag.rb b/app/models/issue_tag.rb index b4ee673f7..7251e98f2 100644 --- a/app/models/issue_tag.rb +++ b/app/models/issue_tag.rb @@ -2,17 +2,18 @@ # # Table name: issue_tags # -# id :integer not null, primary key -# name :string(255) -# description :string(255) -# color :string(255) -# user_id :integer -# project_id :integer -# issues_count :integer default("0") -# created_at :datetime not null -# updated_at :datetime not null -# gid :integer -# gitea_url :string(255) +# id :integer not null, primary key +# name :string(190) +# description :string(255) +# color :string(255) +# user_id :integer +# project_id :integer +# issues_count :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# gid :integer +# gitea_url :string(255) +# pull_requests_count :integer default("0") # # Indexes # diff --git a/app/models/laboratory.rb b/app/models/laboratory.rb index 9b409c170..0517c0df6 100644 --- a/app/models/laboratory.rb +++ b/app/models/laboratory.rb @@ -10,7 +10,6 @@ # sync_course :boolean default("0") # sync_subject :boolean default("0") # sync_shixun :boolean default("0") -# is_local :boolean default("0") # # Indexes # diff --git a/app/models/license.rb b/app/models/license.rb index d14a9db14..f84e63573 100644 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -7,6 +7,7 @@ # content :text(65535) # created_at :datetime not null # updated_at :datetime not null +# is_secret :boolean default("0") # class License < ApplicationRecord diff --git a/app/models/mark_file.rb b/app/models/mark_file.rb index c6c834623..663f6aca4 100644 --- a/app/models/mark_file.rb +++ b/app/models/mark_file.rb @@ -1,3 +1,23 @@ +# == Schema Information +# +# Table name: mark_files +# +# id :integer not null, primary key +# pull_request_id :integer +# user_id :integer +# file_path_sha :string(255) +# file_path :string(255) +# mark_as_read :boolean default("0") +# updated_after_read :boolean default("0") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_mark_files_on_file_path_sha (file_path_sha) +# index_mark_files_on_pull_request_id (pull_request_id) +# + class MarkFile < ApplicationRecord belongs_to :pull_request diff --git a/app/models/member.rb b/app/models/member.rb index 521f939c5..aaaf34efc 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -11,6 +11,7 @@ # course_group_id :integer default("0") # is_collect :integer default("1") # graduation_group_id :integer default("0") +# is_apply_signature :boolean default("0") # team_user_id :integer # # Indexes diff --git a/app/models/message_template/issue_creator_expire.rb b/app/models/message_template/issue_creator_expire.rb index e6f42fcc4..c9478aa53 100644 --- a/app/models/message_template/issue_creator_expire.rb +++ b/app/models/message_template/issue_creator_expire.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: message_templates +# +# id :integer not null, primary key +# type :string(255) +# sys_notice :text(65535) +# email :text(65535) +# created_at :datetime not null +# updated_at :datetime not null +# notification_url :string(255) +# email_title :string(255) +# + class MessageTemplate::IssueCreatorExpire < MessageTemplate -end \ No newline at end of file +end diff --git a/app/models/organization.rb b/app/models/organization.rb index 75a2db971..cb829626e 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -46,11 +46,10 @@ # is_sync_pwd :boolean default("1") # watchers_count :integer default("0") # devops_step :integer default("0") -# sponsor_certification :integer default("0") -# sponsor_num :integer default("0") -# sponsored_num :integer default("0") -# sponsor_description :text(65535) -# award_time :datetime +# sign_cla :boolean default("0") +# enabling_cla :boolean default("0") +# id_card_verify :boolean default("0") +# website_permission :boolean default("0") # # Indexes # @@ -58,7 +57,7 @@ # 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_login (login) UNIQUE # index_users_on_mail (mail) # index_users_on_type (type) # @@ -70,6 +69,8 @@ class Organization < Owner default_scope { where(type: "Organization") } has_one :organization_extension, dependent: :destroy + has_one :cla, dependent: :destroy + has_many :teams, dependent: :destroy has_many :organization_users, dependent: :destroy has_many :team_users, dependent: :destroy @@ -108,6 +109,16 @@ class Organization < Owner organization_users.where(user_id: user_id).present? end + def is_sign?(user_id) + return false if cla.nil? + cla.user_clas.where(user_id: user_id, state: 1).present? + end + + def cla_sign_email(user_id) + cla.user_clas.find_by(user_id: user_id)&.email + end + + def is_owner?(user_id) team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(owner)}).present? end @@ -126,14 +137,24 @@ class Organization < Owner def is_only_admin?(user_id) team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(admin)}).present? + roles = has_roles(user_id) + roles.size > 1 ? false : roles.include?("admin") end def is_only_write?(user_id) - team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(write)}).present? + # team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(write)}).present? + roles = has_roles(user_id) + roles.size > 1 ? false : roles.include?("write") end def is_only_read?(user_id) - team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(read)}).present? + # team_users.joins(:team).where(user_id: user_id, teams: {authorize: %w(read)}).present? + roles = has_roles(user_id) + roles.size > 1 ? false : roles.include?("read") + end + + def has_roles(user_id) + teams.joins(:team_users).where("team_users.user_id=?", user_id).pluck("teams.authorize").uniq end # 是不是所有者团队的最后一个成员 @@ -183,4 +204,17 @@ class Organization < Owner name end end + + def open_cla! + update_attribute(:enabling_cla, true) + end + + def close_cla! + update_attribute(:enabling_cla, false) + end + + def open_cla? + enabling_cla == true + end + end diff --git a/app/models/organization_extension.rb b/app/models/organization_extension.rb index cb216aca1..11f0c7694 100644 --- a/app/models/organization_extension.rb +++ b/app/models/organization_extension.rb @@ -19,6 +19,8 @@ # news_banner_id :integer # news_content :text(65535) # memo :text(65535) +# news_title :string(255) +# news_url :string(255) # # Indexes # diff --git a/app/models/organization_user.rb b/app/models/organization_user.rb index 4ff6946b7..900710a9a 100644 --- a/app/models/organization_user.rb +++ b/app/models/organization_user.rb @@ -5,6 +5,7 @@ # 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 # diff --git a/app/models/page.rb b/app/models/page.rb new file mode 100644 index 000000000..57a30acad --- /dev/null +++ b/app/models/page.rb @@ -0,0 +1,56 @@ +# == Schema Information +# +# Table name: pages +# +# id :integer not null, primary key +# user_id :integer not null +# project_id :integer not null +# identifier :string(255) +# site_name :string(255) +# language_frame :integer default("0") +# theme :string(255) +# last_build_at :datetime +# state :boolean default("1") +# state_description :string(255) +# created_at :datetime not null +# updated_at :datetime not null +# last_build_info :text(65535) +# build_state :boolean +# +# Indexes +# +# index_pages_on_project_id (project_id) +# index_pages_on_user_id (user_id) +# + +class Page < ApplicationRecord + belongs_to :user + belongs_to :project + + # language_frame 前端语言框架 + enum language_frame: { hugo: 0, jekyll: 1, hexo: 2} + + after_create do + PageService.genernate_user(user_id) + end + + before_save do + if state_changed? && state == false + PageService.close_site(user_id, identifier) + end + end + + def deploy_page(branch) + PageService.deploy_page(branch,self.id) + end + + def url + @deploy_domain = EduSetting.find_by_name("site_page_deploy_domain").try(:value) + "http://#{user.login}.#{@deploy_domain}/#{identifier}" + end + + def build_script_path + "#{language_frame}_build" + end + +end diff --git a/app/models/page_theme.rb b/app/models/page_theme.rb new file mode 100644 index 000000000..bce3d5f70 --- /dev/null +++ b/app/models/page_theme.rb @@ -0,0 +1,29 @@ +# == Schema Information +# +# Table name: page_themes +# +# id :integer not null, primary key +# name :string(255) not null +# language_frame :integer default("0") +# image_url :string(255) +# clone_url :string(255) not null +# order_index :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# + +class PageTheme < ApplicationRecord + enum language_frame: { hugo: 0, jeklly: 1, hexo: 2} + validates :name, presence: {message: "主题名不能为空"}, uniqueness: {message: "主题名已存在",scope: :language_frame},length: {maximum: 255} + + def image + page_image_url('image') + end + private + + def page_image_url(type) + return nil unless Util::FileManage.exists?(self, type) + Util::FileManage.source_disk_file_url(self, type) + end + +end diff --git a/app/models/praise_tread.rb b/app/models/praise_tread.rb index 0250f012e..0618aa575 100644 --- a/app/models/praise_tread.rb +++ b/app/models/praise_tread.rb @@ -1,19 +1,20 @@ -# == Schema Information -# -# Table name: praise_treads -# -# id :integer not null, primary key -# user_id :integer not null -# praise_tread_object_id :integer -# praise_tread_object_type :string(255) -# praise_or_tread :integer default("1") -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# praise_tread (praise_tread_object_id,praise_tread_object_type) -# +# == Schema Information +# +# Table name: praise_treads +# +# id :integer not null, primary key +# user_id :integer not null +# praise_tread_object_id :integer +# praise_tread_object_type :string(255) +# praise_or_tread :integer default("1") +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# praise_tread (praise_tread_object_id,praise_tread_object_type) +# + class PraiseTread < ApplicationRecord diff --git a/app/models/project.rb b/app/models/project.rb index a63a8dd42..5f9fcef68 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3,7 +3,7 @@ # Table name: projects # # id :integer not null, primary key -# name :string(255) +# name :string(190) # description :text(4294967295) # homepage :string(255) default("") # is_public :boolean default("1"), not null @@ -57,17 +57,22 @@ # lesson_url :string(255) # is_pinned :boolean default("0") # recommend_index :integer default("0") +# use_blockchain :boolean default("0") +# pr_view_admin :boolean default("0") # # Indexes # +# index_projects_on_forked_count (forked_count) # index_projects_on_forked_from_project_id (forked_from_project_id) # index_projects_on_identifier (identifier) # index_projects_on_invite_code (invite_code) +# index_projects_on_is_pinned (is_pinned) # index_projects_on_is_public (is_public) # index_projects_on_lft (lft) # index_projects_on_license_id (license_id) # index_projects_on_name (name) # index_projects_on_platform (platform) +# index_projects_on_praises_count (praises_count) # index_projects_on_project_category_id (project_category_id) # index_projects_on_project_language_id (project_language_id) # index_projects_on_project_type (project_type) @@ -75,6 +80,7 @@ # index_projects_on_rgt (rgt) # index_projects_on_status (status) # index_projects_on_updated_on (updated_on) +# index_projects_on_user_id (user_id) # class Project < ApplicationRecord @@ -114,6 +120,7 @@ class Project < ApplicationRecord has_many :issues, dependent: :destroy # has_many :user_grades, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy + has_one :page, dependent: :destroy has_one :project_score, dependent: :destroy has_many :versions, -> { order("versions.created_on DESC, versions.name DESC") }, dependent: :destroy has_many :praise_treads, as: :praise_tread_object, dependent: :destroy diff --git a/app/models/project_category.rb b/app/models/project_category.rb index 97a304259..bc6f8427d 100644 --- a/app/models/project_category.rb +++ b/app/models/project_category.rb @@ -15,6 +15,7 @@ # Indexes # # index_project_categories_on_ancestry (ancestry) +# index_project_categories_on_id (id) # class ProjectCategory < ApplicationRecord diff --git a/app/models/project_language.rb b/app/models/project_language.rb index 0770a1efa..22a4a81ff 100644 --- a/app/models/project_language.rb +++ b/app/models/project_language.rb @@ -9,6 +9,10 @@ # created_at :datetime not null # updated_at :datetime not null # +# Indexes +# +# index_project_languages_on_id (id) +# class ProjectLanguage < ApplicationRecord include Projectable diff --git a/app/models/pull_request.rb b/app/models/pull_request.rb index e46777951..0142f27f6 100644 --- a/app/models/pull_request.rb +++ b/app/models/pull_request.rb @@ -24,10 +24,11 @@ # class PullRequest < ApplicationRecord - #status 0 默认未合并, 1表示合并, 2表示请求拒绝(或已关闭) + #status 0 默认未合并, 1表示合并, 2表示请求拒绝(或已关闭) ,3 表示未签署CLA OPEN = 0 MERGED = 1 CLOSED = 2 + NEEDCLA = 3 belongs_to :issue belongs_to :user diff --git a/app/models/repository.rb b/app/models/repository.rb index c60164001..7d3f207ea 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -27,6 +27,8 @@ # # Indexes # +# index_name (project_id) +# index_repositories_on_identifier (identifier) # index_repositories_on_project_id (project_id) # index_repositories_on_user_id (user_id) # @@ -43,6 +45,7 @@ class Repository < ApplicationRecord validates :identifier, presence: true delegate :default_branch, to: :project, allow_nil: true + attr_accessor :auth_token def to_param self.identifier.parameterize diff --git a/app/models/school.rb b/app/models/school.rb index 5b30be9a5..d7a41c914 100644 --- a/app/models/school.rb +++ b/app/models/school.rb @@ -15,23 +15,6 @@ # auto_users_trial :boolean default("0") # shool_code :string(255) # authorization_time :datetime -# ec_auth :integer default("0") -# identifier :string(255) -# is_online :boolean default("0") -# video_name :string(255) -# video_desc :string(255) -# course_link :string(255) -# course_name :string(255) -# partner_id :integer -# customer_id :integer -# school_property_id :integer -# -# Indexes -# -# index_schools_on_customer_id (customer_id) -# index_schools_on_identifier (identifier) -# index_schools_on_partner_id (partner_id) -# index_schools_on_school_property_id (school_property_id) # class School < ApplicationRecord diff --git a/app/models/system_notification_history.rb b/app/models/system_notification_history.rb index b629babdf..9ecfc5bb8 100644 --- a/app/models/system_notification_history.rb +++ b/app/models/system_notification_history.rb @@ -2,16 +2,16 @@ # # Table name: system_notification_histories # -# id :integer not null, primary key -# system_message_id :integer -# user_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# system_notification_id :integer +# user_id :integer +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_system_notification_histories_on_system_message_id (system_message_id) -# index_system_notification_histories_on_user_id (user_id) +# index_system_notification_histories_on_system_notification_id (system_notification_id) +# index_system_notification_histories_on_user_id (user_id) # class SystemNotificationHistory < ApplicationRecord diff --git a/app/models/template_message_setting.rb b/app/models/template_message_setting.rb index 67f9586d0..5e4907b2e 100644 --- a/app/models/template_message_setting.rb +++ b/app/models/template_message_setting.rb @@ -6,9 +6,9 @@ # type :string(255) # name :string(255) # key :string(255) -# openning :boolean -# notification_disabled :boolean -# email_disabled :boolean +# openning :boolean default("1") +# notification_disabled :boolean default("1") +# email_disabled :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/template_message_setting/create_or_assign.rb b/app/models/template_message_setting/create_or_assign.rb index 4c392b4b7..629051305 100644 --- a/app/models/template_message_setting/create_or_assign.rb +++ b/app/models/template_message_setting/create_or_assign.rb @@ -6,9 +6,9 @@ # type :string(255) # name :string(255) # key :string(255) -# openning :boolean -# notification_disabled :boolean -# email_disabled :boolean +# openning :boolean default("1") +# notification_disabled :boolean default("1") +# email_disabled :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/template_message_setting/manage_project.rb b/app/models/template_message_setting/manage_project.rb index 978761f94..c9b2406d7 100644 --- a/app/models/template_message_setting/manage_project.rb +++ b/app/models/template_message_setting/manage_project.rb @@ -6,9 +6,9 @@ # type :string(255) # name :string(255) # key :string(255) -# openning :boolean -# notification_disabled :boolean -# email_disabled :boolean +# openning :boolean default("1") +# notification_disabled :boolean default("1") +# email_disabled :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/template_message_setting/normal.rb b/app/models/template_message_setting/normal.rb index 771fba2f2..acf44009f 100644 --- a/app/models/template_message_setting/normal.rb +++ b/app/models/template_message_setting/normal.rb @@ -6,9 +6,9 @@ # type :string(255) # name :string(255) # key :string(255) -# openning :boolean -# notification_disabled :boolean -# email_disabled :boolean +# openning :boolean default("1") +# notification_disabled :boolean default("1") +# email_disabled :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/template_message_setting/watch_project.rb b/app/models/template_message_setting/watch_project.rb index 35dfef6db..a07e4bb94 100644 --- a/app/models/template_message_setting/watch_project.rb +++ b/app/models/template_message_setting/watch_project.rb @@ -6,9 +6,9 @@ # type :string(255) # name :string(255) # key :string(255) -# openning :boolean -# notification_disabled :boolean -# email_disabled :boolean +# openning :boolean default("1") +# notification_disabled :boolean default("1") +# email_disabled :boolean default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/timeable_visit_record.rb b/app/models/timeable_visit_record.rb index 8411ddf66..aee1d718f 100644 --- a/app/models/timeable_visit_record.rb +++ b/app/models/timeable_visit_record.rb @@ -5,7 +5,7 @@ # id :integer not null, primary key # time :string(255) # project_id :integer -# visits :integer +# visits :integer default("0") # created_at :datetime not null # updated_at :datetime not null # diff --git a/app/models/token.rb b/app/models/token.rb index 746af6535..fac516eb8 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -1,18 +1,19 @@ -# == Schema Information -# -# Table name: tokens -# -# id :integer not null, primary key -# user_id :integer default("0"), not null -# action :string(30) default(""), not null -# value :string(40) default(""), not null -# created_on :datetime not null -# -# Indexes -# -# index_tokens_on_user_id (user_id) -# tokens_value (value) UNIQUE -# +# == Schema Information +# +# Table name: tokens +# +# id :integer not null, primary key +# user_id :integer default("0"), not null +# action :string(30) default(""), not null +# value :string(40) default(""), not null +# created_on :datetime not null +# +# Indexes +# +# index_tokens_on_user_id (user_id) +# tokens_value (value) UNIQUE +# + # # This program is free software; you can redistribute it and/or diff --git a/app/models/topic.rb b/app/models/topic.rb index e464859ec..163c2afdd 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # @@ -42,11 +41,36 @@ class Topic < ApplicationRecord end end + + def get_visitor_data + data = { + visits: 0, + created_time: format_time(Time.now), + from:"other" + } + + if self.url.include?("gitlink.org.cn/forums/") || self.url.include?("trustie.net/forums/") + request_memo = Forum::Memos::GetService.call(self.uuid) + data[:visits] = request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"] + data[:created_time] = request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"] + data[:from] = "forums" + end + + if self.url.include?("gitlink.org.cn/zone/") || self.url.include?("trustie.net/zone/") + request_doc = Getway::Cms::GetService.call(self.uuid) + data[:visits] = request_doc.nil? ? 0 : request_doc["data"]["visits"] + data[:created_time] = request_doc.nil? ? format_time(Time.now) : request_doc["data"]["publishTime"] + data[:from] = "zone" + end + + data + end + private def image_url(type) - return nil unless Util::FileManage.exists?(self, type) - Util::FileManage.source_disk_file_url(self, type) + return nil unless Util::FileManage.exists?(self, type) + Util::FileManage.source_disk_file_url(self, type) end end diff --git a/app/models/topic/activity_forum.rb b/app/models/topic/activity_forum.rb index 8cf9adf83..ee2dc9941 100644 --- a/app/models/topic/activity_forum.rb +++ b/app/models/topic/activity_forum.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/banner.rb b/app/models/topic/banner.rb index e5b77bec0..7abd2ac56 100644 --- a/app/models/topic/banner.rb +++ b/app/models/topic/banner.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/card.rb b/app/models/topic/card.rb index 6a54e17ea..3baee486c 100644 --- a/app/models/topic/card.rb +++ b/app/models/topic/card.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/cooperator.rb b/app/models/topic/cooperator.rb index a023d3656..0fab2c3b7 100644 --- a/app/models/topic/cooperator.rb +++ b/app/models/topic/cooperator.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/excellent_project.rb b/app/models/topic/excellent_project.rb index ac08863c7..aec097f62 100644 --- a/app/models/topic/excellent_project.rb +++ b/app/models/topic/excellent_project.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/experience_forum.rb b/app/models/topic/experience_forum.rb index 855a56809..9b48f9ed4 100644 --- a/app/models/topic/experience_forum.rb +++ b/app/models/topic/experience_forum.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/topic/glcc_news.rb b/app/models/topic/glcc_news.rb index 6b707bf07..4b2e758d2 100644 --- a/app/models/topic/glcc_news.rb +++ b/app/models/topic/glcc_news.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # @@ -14,4 +13,4 @@ # GLCC 新闻稿 class Topic::GlccNews < Topic -end \ No newline at end of file +end diff --git a/app/models/topic/pinned_forum.rb b/app/models/topic/pinned_forum.rb index c5a2c8572..78425ce6a 100644 --- a/app/models/topic/pinned_forum.rb +++ b/app/models/topic/pinned_forum.rb @@ -6,7 +6,6 @@ # type :string(255) # title :string(255) # uuid :integer -# image_url :string(255) # url :string(255) # order_index :integer # diff --git a/app/models/user.rb b/app/models/user.rb index ba8afffa4..8f1e29547 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,15 +39,17 @@ # business :boolean default("0") # profile_completed :boolean default("0") # laboratory_id :integer -# is_shixun_marker :boolean default("0") -# admin_visitable :boolean default("0") -# collaborator :boolean default("0") +# 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") -# gitea_token :string(255) -# platform :string(255) +# sign_cla :boolean default("0") +# enabling_cla :boolean default("0") +# id_card_verify :boolean default("0") +# website_permission :boolean default("0") # # Indexes # @@ -56,8 +58,7 @@ # index_users_on_homepage_teacher (homepage_teacher) # index_users_on_laboratory_id (laboratory_id) # index_users_on_login (login) UNIQUE -# index_users_on_mail (mail) UNIQUE -# index_users_on_phone (phone) UNIQUE +# index_users_on_mail (mail) # index_users_on_type (type) # @@ -121,19 +122,20 @@ class User < Owner has_many :open_users, dependent: :destroy has_one :wechat_open_user, class_name: 'OpenUsers::Wechat' has_one :qq_open_user, class_name: 'OpenUsers::Qq' + has_one :identity_verification accepts_nested_attributes_for :user_extension, update_only: true has_many :fork_users, dependent: :destroy has_many :versions has_many :issue_times, :dependent => :destroy - has_one :onclick_time, :dependent => :destroy + # has_one :onclick_time, :dependent => :destroy # 新版私信 - has_many :private_messages, dependent: :destroy + # has_many :private_messages, dependent: :destroy has_many :recent_contacts, through: :private_messages, source: :target has_many :tidings, :dependent => :destroy - has_many :journals_for_messages, :as => :jour, :dependent => :destroy + # has_many :journals_for_messages, :as => :jour, :dependent => :destroy has_many :attachments,foreign_key: :author_id, :dependent => :destroy @@ -143,7 +145,7 @@ class User < Owner has_many :apply_user_authentication has_one :process_real_name_apply, -> { processing.real_name_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' has_one :process_professional_apply, -> { processing.professional_auth.order(created_at: :desc) }, class_name: 'ApplyUserAuthentication' - has_many :apply_actions, dependent: :destroy + # has_many :apply_actions, dependent: :destroy has_many :trail_auth_apply_actions, -> { where(container_type: 'TrialAuthorization') }, class_name: 'ApplyAction' # has_many :attendances @@ -183,12 +185,18 @@ class User < Owner has_many :issue_participants, foreign_key: :participant_id has_many :participant_issues, through: :issue_participants, source: :issue has_many :project_topics + #cla + has_many :user_clas, :dependent => :destroy + has_many :clas, through: :user_clas + + has_many :pages, :dependent => :destroy + # Groups and active users scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) } scope :like, lambda { |keywords| # 表情处理 keywords = keywords.to_s.each_char.select { |c| c.bytes.first < 240 }.join('') - sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search OR mail LIKE :search OR nickname LIKE :search" + sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search OR mail LIKE :search OR phone LIKE :search" where(sql, :search => "%#{keywords.strip}%") unless keywords.blank? } @@ -463,6 +471,23 @@ class User < Owner end end + + def register_gitea + psd = "12345678" + interactor = Gitea::RegisterInteractor.call({username: self.login, email: self.mail, password: psd}) + if interactor.success? + gitea_user = interactor.result + result = Gitea::User::GenerateTokenService.call(self.login, psd) + self.gitea_token = result['sha1'] + self.gitea_uid = gitea_user[:body]['id'] + self.password = psd + self.password_confirmation = psd + if self.save! + UserExtension.create!(user_id: self.id) + end + end + end + def activate! update_attribute(:status, STATUS_ACTIVE) prohibit_gitea_user_login!(false) @@ -738,6 +763,7 @@ class User < Owner if password salt_password(password) end + check_website_permission end def salt_password(clear_password) @@ -745,6 +771,13 @@ class User < Owner self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}") end + def check_website_permission + if website_permission_changed? && website_permission == false + self.pages.update_all(state: false, state_description:"因违规使用,现关闭Page服务") + PageService.close_site(self.id) + end + end + def self.generate_salt Gitlink::Utils.random_hex(16) end @@ -838,7 +871,8 @@ class User < Owner end def profile_is_completed? - self.nickname.present? && self.mail.present? + #self.nickname.present? && self.mail.present? + self.mail.present? end def trace_token @@ -861,7 +895,7 @@ class User < Owner # 重写gitea_token,当用户为bot类型时,替换成管理员token def gitea_token - if self.platform == "bot" + if self.respond_to?('platform') && self.platform == "bot" GiteaService.gitea_config[:admin_token] else self['gitea_token'] diff --git a/app/models/user_action.rb b/app/models/user_action.rb index 179359695..b4173fe77 100644 --- a/app/models/user_action.rb +++ b/app/models/user_action.rb @@ -9,12 +9,14 @@ # created_at :datetime not null # updated_at :datetime not null # ip :string(255) +# data_bank :text(65535) # # Indexes # -# index_user_actions_on_ip (ip) -# index_user_actions_on_user_id (user_id) -# index_user_actions_on_user_id_and_action_type (user_id,action_type) +# index_user_actions_on_action_id (action_id) +# index_user_actions_on_action_type (action_type) +# index_user_actions_on_ip (ip) +# index_user_actions_on_user_id (user_id) # class UserAction < ApplicationRecord diff --git a/app/models/user_agent.rb b/app/models/user_agent.rb index ba519d6fb..49d7b35a1 100644 --- a/app/models/user_agent.rb +++ b/app/models/user_agent.rb @@ -10,13 +10,10 @@ # updated_at :datetime not null # register_status :integer default("0") # action_status :integer default("0") -# is_delete :boolean default("0") -# user_id :integer # # Indexes # -# index_user_agents_on_ip (ip) -# index_user_agents_on_user_id (user_id) +# index_user_agents_on_ip (ip) UNIQUE # class UserAgent < ApplicationRecord diff --git a/app/models/user_cla.rb b/app/models/user_cla.rb new file mode 100644 index 000000000..b109a74fa --- /dev/null +++ b/app/models/user_cla.rb @@ -0,0 +1,63 @@ +# == Schema Information +# +# Table name: user_clas +# +# id :integer not null, primary key +# user_id :integer not null +# cla_id :integer not null +# real_name :string(255) not null +# email :string(255) not null +# state :integer default("0") +# created_at :datetime not null +# updated_at :datetime not null +# sign_time :datetime +# +# Indexes +# +# index_user_clas_on_cla_id (cla_id) +# index_user_clas_on_user_id (user_id) +# + +class UserCla < ApplicationRecord + belongs_to :user + belongs_to :cla +# identity 0: 教师教授 1: 学生, 2: 专业人士, 3: 开发者 + enum state: { deafult: 0, signed: 1, failed: 2} + + after_save do + cla.fresh_count + end + + before_save do + fresh_pull_request + end + + def self.build(params,current_user_id) + self.create!(user_id: current_user_id, + cla_id: params[:cla_id], + real_name: params[:real_name], + email: params[:email], + sign_time: Time.now, + state: 1 + ) + end + + def update_by_params(params) + update(\ + state: 1, + sign_time: Time.now, + real_name: params[:real_name], + email: params[:email], + ) + end + + def fresh_pull_request + project_ids = cla.organization.projects.pluck(:id) + if state == "signed" + PullRequest.where(user_id: user_id, project_id: project_ids, status:3).update_all(status:0) + else + PullRequest.where(user_id: user_id, project_id: project_ids, status:0).update_all(status:3) + end + end + +end diff --git a/app/models/user_extension.rb b/app/models/user_extension.rb index c1046ac2f..aeb9a9d83 100644 --- a/app/models/user_extension.rb +++ b/app/models/user_extension.rb @@ -20,11 +20,11 @@ # student_realname :string(255) # location_city :string(255) # school_id :integer -# description :string(255) default("") +# description :string(255) # department_id :integer -# province :string(255) -# city :string(255) +# province :text(65535) # custom_department :string(255) +# city :string(255) # show_email :boolean default("0") # show_location :boolean default("0") # show_department :boolean default("0") diff --git a/app/models/version.rb b/app/models/version.rb index 82474f55e..ec2ad68cd 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -4,7 +4,7 @@ # # id :integer not null, primary key # project_id :integer default("0"), not null -# name :string(255) default(""), not null +# name :string(255) # description :text(65535) # effective_date :date # created_on :datetime diff --git a/app/models/version_release.rb b/app/models/version_release.rb index 00119f806..98c81b61d 100644 --- a/app/models/version_release.rb +++ b/app/models/version_release.rb @@ -4,9 +4,9 @@ # # id :integer not null, primary key # user_id :integer -# name :string(255) +# name :text(4294967295) # body :text(65535) -# tag_name :string(255) +# tag_name :text(65535) # target_commitish :string(255) # draft :boolean default("0") # prerelease :boolean default("0") diff --git a/app/queries/admins/glcc_examine_material.rb b/app/queries/admins/glcc_examine_material.rb new file mode 100644 index 000000000..4e8f2bea7 --- /dev/null +++ b/app/queries/admins/glcc_examine_material.rb @@ -0,0 +1,29 @@ +class Admins::GlccExamineMaterial < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_on, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + materials = GlccMediumTermExamineMaterial.all + + # term + term = params[:term] || [1,2] + if term.present? + materials = materials.where(term: term) + end + #year + year = if params[:date] + params[:date][:year] + end + year = year || Time.now.year + date = Time.now.change(year:year) + materials = materials.where(created_on: [date.beginning_of_year..date.end_of_year]) + custom_sort(materials, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/identity_verification_query.rb b/app/queries/admins/identity_verification_query.rb new file mode 100644 index 000000000..b0c685ae2 --- /dev/null +++ b/app/queries/admins/identity_verification_query.rb @@ -0,0 +1,17 @@ +class Admins::IdentityVerificationQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + state = params[:state] == "all" ? [0,1,2] : params[:state].nil? ? [0] : params[:state].to_i + applies = IdentityVerification.where(state: state) + custom_sort(applies, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/organization_query.rb b/app/queries/admins/organization_query.rb index 09dbab9e3..ff3f301be 100644 --- a/app/queries/admins/organization_query.rb +++ b/app/queries/admins/organization_query.rb @@ -9,6 +9,8 @@ class Admins::OrganizationQuery < ApplicationQuery def call orgs = Organization.all + + orgs = orgs.where(enabling_cla: params[:enabling_cla]) if params[:enabling_cla].present? # 关键字检索 keyword = params[:keyword].to_s.strip.presence if keyword diff --git a/app/queries/admins/page_themes_query.rb b/app/queries/admins/page_themes_query.rb new file mode 100644 index 000000000..72d40943a --- /dev/null +++ b/app/queries/admins/page_themes_query.rb @@ -0,0 +1,17 @@ +class Admins::PageThemesQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + language_frame = params[:language_frame].blank? ? [0..99] : params[:language_frame] + page_themes = PageTheme.where(language_frame: language_frame) + custom_sort(page_themes, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/admins/site_pages_query.rb b/app/queries/admins/site_pages_query.rb new file mode 100644 index 000000000..75694157c --- /dev/null +++ b/app/queries/admins/site_pages_query.rb @@ -0,0 +1,24 @@ +class Admins::SitePagesQuery < ApplicationQuery + include CustomSortable + + attr_reader :params + + sort_columns :created_at, default_by: :created_at, default_direction: :desc + + def initialize(params) + @params = params + end + + def call + state = params[:state].blank? ? [true,false] : params[:state] + pages = Page.joins(:user).where(state: state) + # 关键字检索 + keyword = params[:keyword].to_s.strip.presence + if keyword + sql = 'users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword' + pages = pages.where(sql, keyword: "%#{keyword}%") + end + + custom_sort(pages, params[:sort_by], params[:sort_direction]) + end +end \ No newline at end of file diff --git a/app/queries/page_query.rb b/app/queries/page_query.rb new file mode 100644 index 000000000..d9496b30e --- /dev/null +++ b/app/queries/page_query.rb @@ -0,0 +1,13 @@ +class PageQuery < ApplicationQuery + attr_reader :params + + def initialize(params, user) + @user = user + @params = params + end + + def call + pages = Page.where(user: @user).order(created_at: :desc) + pages + end +end \ No newline at end of file diff --git a/app/queries/projects/list_query.rb b/app/queries/projects/list_query.rb index 72776f7a2..c67feed61 100644 --- a/app/queries/projects/list_query.rb +++ b/app/queries/projects/list_query.rb @@ -29,6 +29,7 @@ class Projects::ListQuery < ApplicationQuery def filter_projects(collection) # collection = by_pinned(collection) collection = by_search(collection) if params[:search].present? + collection = collection.where(id: params[:ids].to_s.split(",")) if params[:ids].present? collection = by_project_type(collection) collection = by_project_category(collection) collection = by_project_language(collection) diff --git a/app/services/admins/delete_organization_service.rb b/app/services/admins/delete_organization_service.rb index d5c9bd2c5..2a7b4aab1 100644 --- a/app/services/admins/delete_organization_service.rb +++ b/app/services/admins/delete_organization_service.rb @@ -6,9 +6,6 @@ class Admins::DeleteOrganizationService < Gitea::ClientService end def call - response = delete(url, params) - render_status(response) - Gitea::Organization::DeleteService.call(token,name) end diff --git a/app/services/admins/save_laboratory_setting_service.rb b/app/services/admins/save_laboratory_setting_service.rb index c29e374bd..ad040585f 100644 --- a/app/services/admins/save_laboratory_setting_service.rb +++ b/app/services/admins/save_laboratory_setting_service.rb @@ -30,6 +30,7 @@ class Admins::SaveLaboratorySettingService < ApplicationService hash = {} hash[:name] = strip nav[:name] hash[:link] = strip nav[:link] + hash[:index] = strip nav[:index] hash[:hidden] = nav[:hidden].to_s != '0' hash end diff --git a/app/services/admins/update_user_service.rb b/app/services/admins/update_user_service.rb index 9d116cffe..4dd80b9d0 100644 --- a/app/services/admins/update_user_service.rb +++ b/app/services/admins/update_user_service.rb @@ -32,7 +32,7 @@ class Admins::UpdateUserService < ApplicationService def user_attributes params.slice(*%i[lastname nickname mail phone admin business is_test login - professional_certification authentication is_shixun_marker]) + professional_certification authentication is_shixun_marker website_permission]) end def user_extension_attributes diff --git a/app/services/api/v1/issues/list_service.rb b/app/services/api/v1/issues/list_service.rb index 5a3f97e98..b6ef11789 100644 --- a/app/services/api/v1/issues/list_service.rb +++ b/app/services/api/v1/issues/list_service.rb @@ -76,7 +76,7 @@ class Api::V1::Issues::ListService < ApplicationService end # keyword - issues = issues.ransack(id_eq: keyword).result.or(issues.ransack(subject_or_description_cont: keyword).result) if keyword.present? + issues = issues.ransack(id_or_project_issues_index_eq: keyword).result.or(issues.ransack(subject_or_description_cont: keyword).result) if keyword.present? @total_issues_count = issues.distinct.size @closed_issues_count = issues.closed.distinct.size diff --git a/app/services/api/v1/projects/contributors/stat_service.rb b/app/services/api/v1/projects/contributors/stat_service.rb index d264a109b..ab20dd657 100644 --- a/app/services/api/v1/projects/contributors/stat_service.rb +++ b/app/services/api/v1/projects/contributors/stat_service.rb @@ -6,7 +6,7 @@ class Api::V1::Projects::Contributors::StatService < ApplicationService def initialize(project, params, token=nil) @project = project @branch = params[:branch] - @pass_year = params[:pass_year] + @pass_year = params[:pass_year] || 3 @page = params[:page] || 1 @limit = params[:limit] || 15 @owner = project&.owner.login @@ -23,10 +23,10 @@ class Api::V1::Projects::Contributors::StatService < ApplicationService private def request_params param = { - access_token: token + access_token: token, page: page, limit: limit } param.merge!(branch: branch) if branch.present? - param.merge!(pass_year: pass_year) if pass_year.present? + param.merge!(pass_year: @pass_year) param end diff --git a/app/services/api_limit_service.rb b/app/services/api_limit_service.rb new file mode 100644 index 000000000..d22684962 --- /dev/null +++ b/app/services/api_limit_service.rb @@ -0,0 +1,137 @@ +class ApiLimitService < ApplicationService + Error = Class.new(StandardError) + + def initialize() end + + def call + + end + + # 时间窗口法 + def is_action_allowed?(user_id, action_key, period, max_count) + key = "#{user_id}:#{action_key}" + count = $redis_cache.multi do |multi| + multi.incr(key) + multi.expire(key, period) + end + count[0] <= max_count + end + + # 漏桶法 + def is_action_allowed_bucket?(user_id, action_key, capacity, rate) + key = "#{user_id}:#{action_key}" + # now = (("%10.3f" % Time.now.to_f).to_f * 1000).to_i + now = Time.now.to_i + count = $redis_cache.multi do |multi| + multi.zadd(key, now, SecureRandom.uuid.gsub("-", "")) + multi.zremrangebyscore(key, 0, now - capacity) + multi.zcard(key) + multi.expire(key, (capacity / rate + 1).to_i) + end + # puts "count1==#{count}" + # puts "count2==#{count[2]}" + count[2] <= capacity + end + + def is_action_allowed_aaa?(user_id, action_key, period, maxCount) + key = "#{user_id}:#{action_key}" + now = (("%10.3f" % Time.now.to_f).to_f * 1000).to_i + count = $redis_cache.multi do |multi| + # 添加命令 + multi.zadd(key, now, SecureRandom.uuid.gsub("-", "")) + # 清楚无用数据 + multi.zremrangebyscore(key, 0, now - period * 1000) + # 判断规定时间内请求数量 + multi.zcard(key) + # 重新设置过期时间 + multi.expire(key, period + 1) + end + # puts "count1==#{count}" + # puts "count2==#{count[2]}" + count[2] <= maxCount + end + + def sdfsf + + # 每秒钟漏斗的容量 + + capacity = 10 + + + # 漏斗填充速度 + + leak_rate = 0.3 + + # 当前漏斗中的水量 + + current_volume = 0 + + # 上一次漏水的时间 + + last_leak_time = Time.now.to_i + + funnel_name = "tests" + + # $redis_cache.hset(funnel_name, "volume", capacity) + $redis_cache.hset(funnel_name, "last_leak_time", Time.now.to_i) + + # 构造事务命令 + + # result = $redis_cache.multi do |pipe| + # # 把当前时间与上一次漏水时间的差值,作为漏斗流出水量 + # + # pipe.hget(funnel_name, "last_leak_time") + # + # pipe.hset(funnel_name, "last_leak_time", Time.now.to_i) + # + # pipe.hget(funnel_name, "volume") + # + # pipe.hget(funnel_name, "capacity") + # + # pipe.hget(funnel_name, "leak_rate") + # end + + current_volume = $redis_cache.hget(funnel_name, "volume") + last_leak_time = $redis_cache.hget(funnel_name, "last_leak_time") + # 先漏水 + leaked_volume = (Time.now.to_i - last_leak_time.to_i) * leak_rate.to_f + + current_volume = [current_volume.to_f + leaked_volume, capacity.to_f].sort.first + puts "current_volume====#{current_volume}" + # 判断是否可以通过请求 + if current_volume >= 1 + $redis_cache.hset(funnel_name, "volume", current_volume.to_i - 1) + # $redis_cache.hset(funnel_name, "last_leak_time", Time.now.to_i) + true + else + false + end + + end + + def done_test3 + 100.times.each do |t| + if t % 2== 0 + sleep(1) + end + puts "#{t}:res====#{sdfsf}" + end + end + + def done_test + 100.times.each do |t| + if t % 10== 0 + sleep(5) + end + puts "#{t}:res====#{is_action_allowed_bucket?("123", "test2", 10, 0.2)}" + end + end + + def done_test2 + 100.times.each do |t| + sleep(1) + puts "#{t}:res====#{is_action_allowed_aaa?("123", "test3", 10, 5)}" + end + end + +end diff --git a/app/services/getway/client_service.rb b/app/services/getway/client_service.rb new file mode 100644 index 000000000..cd774772e --- /dev/null +++ b/app/services/getway/client_service.rb @@ -0,0 +1,94 @@ +class Getway::ClientService < ApplicationService + attr_reader :url, :params + + PAGINATE_DEFAULT_PAGE = 1 + PAGINATE_DEFAULT_LIMIT = 20 + + def initialize(options={}) + @url = options[:url] + @params = options[:params] + end + + def get(url, params={}) + conn(params).get do |req| + req.url full_url(url, 'get') + params.except(:token).each_pair do |key, value| + req.params["#{key}"] = value + end + end + + # response.headers.each do |k,v| + # puts "#{k}:#{v}" + # end #=> 响应头 + end + + private + def conn(auth={}) + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.response :logger # 显示日志 + req.adapter Faraday.default_adapter + end + end + @client + end + + def base_url + Getway.getway_config[:base_url] + end + + def domain + Getway.getway_config[:domain] + end + + def api_url + [domain, base_url].join('') + end + + def full_url(api_rest, action='post') + url = [api_url, api_rest].join('').freeze + url = action === 'get' ? url : URI.escape(url) + url = URI.escape(url) unless url.ascii_only? + puts "[getway] request url: #{url}" + return url + end + + def render_response(response) + status = response.status + body = response&.body + + # log_error(status, body) + + body, message = get_body_by_status(status, body) + + [status, message, body] + end + + def get_body_by_status(status, body) + body, message = + case status + when 401 then [nil, "401"] + when 404 then [nil, "404"] + when 403 then [nil, "403"] + when 500 then [nil, "500"] + else + if body.present? + body = JSON.parse(body) + fix_body(body) + else + nil + end + end + + [body, message] + end + + def fix_body(body) + return [body, nil] if body.is_a?(Array) || body.is_a?(Hash) + + body['message'].blank? ? [body, nil] : [nil, body['message']] + end + +end diff --git a/app/services/getway/cms/get_service.rb b/app/services/getway/cms/get_service.rb new file mode 100644 index 000000000..6b7050e84 --- /dev/null +++ b/app/services/getway/cms/get_service.rb @@ -0,0 +1,21 @@ +class Getway::Cms::GetService < Getway::ClientService + attr_reader :doc_id + + def initialize(doc_id) + @doc_id = doc_id + end + + def call + response = get(url) + code, message, body = render_response(response) + if code == 200 && body["code"] == 200 + return body + else + return nil + end + end + + def url + "/cms/doc/open/#{doc_id}".freeze + end +end \ No newline at end of file diff --git a/app/services/gitea/client_service.rb b/app/services/gitea/client_service.rb index 62e040d82..5418be159 100644 --- a/app/services/gitea/client_service.rb +++ b/app/services/gitea/client_service.rb @@ -115,6 +115,9 @@ class Gitea::ClientService < ApplicationService url = [api_url(is_hat), api_rest].join('').freeze url = action === 'get' ? url : URI.escape(url) url = URI.escape(url) unless url.ascii_only? + url = url.gsub(")", "%29") if url.to_s.include?(")") + url = url.gsub("]", "%5D") if url.to_s.include?("]") + url = url.gsub("[", "%5B") if url.to_s.include?("[") puts "[gitea] request url: #{url}" return url end diff --git a/app/services/gitea/commit/diff_service.rb b/app/services/gitea/commit/diff_service.rb index 712302505..76bba852a 100644 --- a/app/services/gitea/commit/diff_service.rb +++ b/app/services/gitea/commit/diff_service.rb @@ -16,7 +16,7 @@ class Gitea::Commit::DiffService < Gitea::ClientService end def call - response = get(url, params) + response = get(url, params, true) render_result(response) end diff --git a/app/services/gitea/repository/commits/file_list_service.rb b/app/services/gitea/repository/commits/file_list_service.rb index 14c873fd3..b0bba7abe 100644 --- a/app/services/gitea/repository/commits/file_list_service.rb +++ b/app/services/gitea/repository/commits/file_list_service.rb @@ -20,7 +20,7 @@ class Gitea::Repository::Commits::FileListService < Gitea::ClientService private def params - {sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "", stat: args[:page].to_i != 1 } + {sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "", stat: args[:page].to_i != 1 && args[:limit] !=1 } end def url diff --git a/app/services/gitea/repository/commits/list_service.rb b/app/services/gitea/repository/commits/list_service.rb index 124cf544d..700508539 100644 --- a/app/services/gitea/repository/commits/list_service.rb +++ b/app/services/gitea/repository/commits/list_service.rb @@ -19,7 +19,7 @@ class Gitea::Repository::Commits::ListService < Gitea::ClientService private def params - { sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "" } + { sha: args[:sha] || 'master', page: args[:page] || PAGINATE_DEFAULT_PAGE, limit: args[:limit] || PAGINATE_DEFAULT_LIMIT, token: args[:token] || "", stat: args[:page].to_i != 1 && args[:limit] !=1 } end def url diff --git a/app/services/gitea/repository/entries/create_service.rb b/app/services/gitea/repository/entries/create_service.rb index 14b373335..ac27b3afb 100644 --- a/app/services/gitea/repository/entries/create_service.rb +++ b/app/services/gitea/repository/entries/create_service.rb @@ -53,7 +53,7 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService def status_payload(status, body) case status when 201 then success(json_parse!(body)) - when 403 then error("你没有权限操作!") + when 403 then error("你没有权限操作,请确认该分支是否是保护分支。") when 404 then error("你操作的链接不存在!") when 422 if @body[:new_branch].present? && (@body[:new_branch].include?('/') || @body[:new_branch].include?('\'') || @body[:new_branch].include?('^') || @body[:new_branch].include?('*')) @@ -61,7 +61,9 @@ class Gitea::Repository::Entries::CreateService < Gitea::ClientService else error("#{filepath}文件已存在,不能重复创建!") end - else error("系统错误!") + else + Rails.logger.error("Gitea api url==#{url},status:#{status},body=#{body}") + error("系统错误!") end end end diff --git a/app/services/gitea/repository/fork_service.rb b/app/services/gitea/repository/fork_service.rb index c43a9ddf2..ca0c0fe68 100644 --- a/app/services/gitea/repository/fork_service.rb +++ b/app/services/gitea/repository/fork_service.rb @@ -1,5 +1,5 @@ class Gitea::Repository::ForkService < Gitea::ClientService - attr_reader :old_owner, :target_owner, :repo_name, :organization + attr_reader :old_owner, :target_owner, :repo_name, :organization, :new_identifier # old_owner: 被clone的项目(源项目)拥有者 # target_owner: clone后的醒目(新项目)的拥有者 @@ -7,10 +7,12 @@ class Gitea::Repository::ForkService < Gitea::ClientService # { # "organization": "string" #组织名称 # } - def initialize(old_owner, target_owner, repo_name, organization=nil) + def initialize(old_owner, target_owner, repo_name, organization=nil, new_identifier=nil) @old_owner = old_owner @target_owner = target_owner @repo_name = repo_name + @organization = organization + @new_identifier = new_identifier end def call @@ -24,6 +26,7 @@ class Gitea::Repository::ForkService < Gitea::ClientService def request_params hash = Hash.new.merge(token: target_owner.gitea_token) hash = hash.merge(data: {organization: organization}) if organization + hash = hash.merge(data: {name: new_identifier}) if new_identifier hash end diff --git a/app/services/gitea/repository/migrate_service.rb b/app/services/gitea/repository/migrate_service.rb index ab60b42f3..c605df0bb 100644 --- a/app/services/gitea/repository/migrate_service.rb +++ b/app/services/gitea/repository/migrate_service.rb @@ -34,6 +34,9 @@ class Gitea::Repository::MigrateService < Gitea::ClientService response = post(url, request_params) render_response(response) + rescue => e + puts "MigrateService error: #{e.message}" + [500, e.message, ""] end private diff --git a/app/services/gitea/user/get_token_service.rb b/app/services/gitea/user/get_token_service.rb index 22d9cc590..d751ca9f4 100644 --- a/app/services/gitea/user/get_token_service.rb +++ b/app/services/gitea/user/get_token_service.rb @@ -8,20 +8,17 @@ class Gitea::User::GetTokenService < Gitea::ClientService def call params = {} - url = "/users/#{username}".freeze - params = params.merge(data: request_params) - get(url, params) + url = "/users/#{username}/tokens".freeze + params = params.merge(sudo: username, page: 1, limit: 200, token: token) + response = get(url, params) + render_status(response) end private - # def token_params - # { - # username: username, - # password: password - # } - # end - - def request_params - { username: username } + def token + { + username: GiteaService.gitea_config[:access_key_id], + password: GiteaService.gitea_config[:access_key_secret] + } end end diff --git a/app/services/gitea/user/register_service.rb b/app/services/gitea/user/register_service.rb index f9e42e9e5..afea81080 100644 --- a/app/services/gitea/user/register_service.rb +++ b/app/services/gitea/user/register_service.rb @@ -31,7 +31,7 @@ class Gitea::User::RegisterService < Gitea::ClientService case status when 201 then success(body) else - error(message, status) + error(message || body["message"], status) end end diff --git a/app/services/leaky_bucket_rate_limiter.rb b/app/services/leaky_bucket_rate_limiter.rb new file mode 100644 index 000000000..2508e99e0 --- /dev/null +++ b/app/services/leaky_bucket_rate_limiter.rb @@ -0,0 +1,42 @@ +class LeakyBucketRateLimiter + def initialize(user_id, rate, capacity) + @rate = rate # 令牌发放速率(每秒发放的令牌数) + @capacity = capacity # 桶的容量(最大令牌数) + @redis = $redis_cache + @key = "#{user_id}:LeakyBucket" + @current_time = Time.now.to_f + end + + def allow_request + current_time = Time.now.to_f + last_drip_time = @redis.getset(@key + ':last_drip_time', current_time).to_f + tokens = @redis.getset(@key + ':tokens', @capacity).to_i + + # 计算已经漏掉的令牌数量 + leaked_tokens = (current_time - last_drip_time) * @rate + puts leaked_tokens + # 如果桶中的令牌多于漏掉的令牌数量,则漏水 + tokens = [@capacity, tokens + leaked_tokens].min + puts tokens + if tokens >= 1 + @redis.set(@key + ':last_drip_time', current_time) + @redis.decr(@key + ':tokens') + return true + end + false + end +end + + +=begin + 失败 + limiter = LeakyBucketRateLimiter.new(110,10, 40) # 设置令牌发放速率为10,桶的容量为40 + 30.times do + if limiter.allow_request + puts "Allow" + else + puts "Reject" + end + end + +=end \ No newline at end of file diff --git a/app/services/page_service.rb b/app/services/page_service.rb new file mode 100644 index 000000000..687added1 --- /dev/null +++ b/app/services/page_service.rb @@ -0,0 +1,58 @@ +require 'net/http' +require 'uri' + +class PageService + + def self.get_deploykey() + @deploy_key = EduSetting.find_by_name("site_page_deploy_key").try(:value) + @deploy_domain = EduSetting.find_by_name("site_page_deploy_domain").try(:value) + end + + + def self.genernate_user(user_id) + get_deploykey() + Rails.logger.info "################### PageService genernate_user #{user_id}" + user = User.find user_id + if user.id_card_verify == true && user.website_permission == true + uri = URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=create_dir&owner=#{user.login.downcase}") + response = Net::HTTP.get_response(uri) + end + Rails.logger.info "################### PageService genernate_user end #{response.body}" + return response.body + end + + def self.close_site(user_id,identifier=nil) + get_deploykey() + Rails.logger.info "################### PageService close_site #{user_id} / #{identifier}" + user = User.find user_id + uri = if identifier.present? + URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=remove_dir&owner=#{user.login.downcase}/#{identifier}/") + else + URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=remove_dir&owner=#{user.login.downcase}/") + end + response = Net::HTTP.get_response(uri) + Rails.logger.info "################### PageService close_site end #{response.body}" + return response.body + end + + def self.deploy_page(branch, page_id) + get_deploykey() + Rails.logger.info "################### PageService deploy #{branch} for page #{page_id}" + page = Page.find page_id + user = page.user + project = page.project + owner = user.login.downcase + + project_dir = page.identifier + repo_link = project.repository.url + repo = project.repository.identifier + branch = branch + script_path =page.build_script_path + if script_path.present? + uri = URI.parse("http://gitlink.#{@deploy_domain}/gitlink_execute_script?key=#{@deploy_key}&script_path=#{script_path}&project_dir=#{project_dir}&repo=#{repo}&repo_link=#{repo_link}&branch=#{branch}&owner=#{owner}") + response = Net::HTTP.get_response(uri) + Rails.logger.info "################### PageService deploy #{response.body}" + return response.body + end + end +end \ No newline at end of file diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index f8b38df47..37edf56ee 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -1,10 +1,12 @@ class Projects::ForkService < ApplicationService - attr_reader :target_owner, :project, :organization + attr_reader :target_owner, :project, :organization, :new_name, :new_identifier - def initialize(target_owner, project, organization=nil) + def initialize(target_owner, project, organization=nil, new_name=nil, new_identifier=nil) @target_owner = target_owner @project = project @organization = organization + @new_name = new_name + @new_identifier = new_identifier end def call @@ -15,11 +17,12 @@ class Projects::ForkService < ApplicationService :rep_identifier, :project_category_id, :project_language_id, :license_id, :ignore_id, {repository: [:identifier, :hidden]}] - result = Gitea::Repository::ForkService.new(@project.owner, @target_owner, @project.identifier, @organization).call - + result = Gitea::Repository::ForkService.new(@project.owner, @target_owner, @project.identifier, @organization, @new_identifier).call clone_project.owner = @target_owner clone_project.forked_from_project_id = @project.id clone_project.gpid = result['id'] + clone_project.name = @new_name if @new_name.present? + clone_project.identifier = @new_identifier if @new_identifier.present? clone_project.save! new_repository = clone_project.repository diff --git a/app/services/projects/migrate_service.rb b/app/services/projects/migrate_service.rb index 68ed9f642..f157ada1d 100644 --- a/app/services/projects/migrate_service.rb +++ b/app/services/projects/migrate_service.rb @@ -9,7 +9,6 @@ class Projects::MigrateService < ApplicationService def call raise Error, "user_id不正确." unless authroize_user_id_success - @project = Project.new(project_params) if @project.save! ProjectUnit.init_types(@project.id, project.project_type) @@ -55,6 +54,7 @@ class Projects::MigrateService < ApplicationService user_id: params[:user_id], login: params[:auth_username], password: params[:auth_password], + auth_token: params[:auth_token], is_mirror: params[:is_mirror], source_clone_url: params[:source_clone_url] } diff --git a/app/services/projects/verify_auth_token_service.rb b/app/services/projects/verify_auth_token_service.rb new file mode 100644 index 000000000..36dcb106f --- /dev/null +++ b/app/services/projects/verify_auth_token_service.rb @@ -0,0 +1,83 @@ +class Projects::VerifyAuthTokenService < ApplicationService + attr_accessor :url, :token + + def initialize(url, token) + @url = url + @token = token + @repo = nil + @owner = nil + @website = nil + @success = false + end + + def call + Rails.logger.info("###### VerifyAuthTokenService begin ######") + regular_url + to_verify + Rails.logger.info("##### VerifyAuthTokenService end ######") + return @success + end + + private + def regular_url + regx = /\/\/[\s\S]*.git$/ #获取字串 + data = (regx.match @url).to_s[2..-5].split("/") + @website = data[0] + @owner = data[1] + @repo = data[2] + end + + + def to_verify + data = case @website + when "github.com" + github_verify + when "gitlab.com" + gitlab_verify + when "gitee.com" + gitee_verify + end + end + + def gitee_verify + url = "/api/v5/repos/#{@owner}/#{@repo}" + api_url= "https://gitee.com" + client = Faraday.new(url: api_url) + client.options["open_timeout"] = 1 + client.options["timeout"] = 1 + client.options["write_timeout"] = 1 + req_params={ + access_token: @token, + owner: @owner, + repo: @repo + } + response = client.public_send("get", url, req_params) + @success = true if response.status == 200 + end + + def github_verify + url = "/octocat" + api_url= "https://api.github.com" + client = Faraday.new(url: api_url) + client.options["open_timeout"] = 1 + client.options["timeout"] = 1 + client.options["write_timeout"] = 1 + client.headers["Authorization"] = "Bearer #{@token}" + response = client.public_send("get", url) + @success = true if response.status == 200 + end + + def gitlab_verify + url = "/api/v4/projects" + api_url= "https://gitlab.com" + client = Faraday.new(url: api_url) + client.options["open_timeout"] = 1 + client.options["timeout"] = 1 + client.options["write_timeout"] = 1 + req_params={ + private_token: @token + } + response = client.public_send("get", url, req_params) + @success = true if response.status == 200 + end +end \ No newline at end of file diff --git a/app/services/pull_requests/create_service.rb b/app/services/pull_requests/create_service.rb index 2b4767f31..070b564d9 100644 --- a/app/services/pull_requests/create_service.rb +++ b/app/services/pull_requests/create_service.rb @@ -180,7 +180,7 @@ class PullRequests::CreateService < ApplicationService end def compare_head_base! - head = pull_request.is_original && @params[:merge_user_login] ? "#{@params[:merge_user_login]}/#{@project.identifier}:#{@params[:head]}" : @params[:head] + head = pull_request.is_original && @params[:merge_user_login] ? "#{@params[:merge_user_login]}/#{@params[:merge_project_identifier]}:#{@params[:head]}" : @params[:head] compare_result = Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(@params[:base]), Addressable::URI.escape(head), @current_user.gitea_token) raise '分支内容相同,无需创建合并请求' if compare_result["Commits"].blank? && compare_result["Diff"].blank? end diff --git a/app/services/pull_requests/send_journal_service.rb b/app/services/pull_requests/send_journal_service.rb new file mode 100644 index 000000000..578faa4b9 --- /dev/null +++ b/app/services/pull_requests/send_journal_service.rb @@ -0,0 +1,34 @@ +class PullRequests::SendJournalService < ApplicationService + + def initialize(project, pull_request,current_user) + @project = project + @pull_request = pull_request + @issue = pull_request.issue + @current_user = current_user + @org = project.owner + end + + def call + if @org.enabling_cla && @org.cla.present? && @org.cla.pr_need && !@org.is_member?(@current_user&.id) && !@org.cla.valid_sign(@current_user&.id) + ActiveRecord::Base.transaction do + sender_id = if Rails.env.development? + User.last.id + else + 87461 + end + journal_params = { + journalized_id: @issue.id , + journalized_type: "Issue", + user_id: sender_id , + notes: "#{@current_user.nickname}您好!欢迎参与 #{@project.name} 的贡献。首次进行贡献请完成《#{@project.owner.cla.name}》的签署,签署完成后,项目成员才可查看到您的合并请求", + } + journal = Journal.new journal_params + if journal.save + @pull_request.update_attributes(status: 3) + TouchWebhookJob.set(wait: 5.seconds).perform_later('PullRequestComment', @issue&.id, sender_id, journal.id, 'created', {}) + push_activity_2_blockchain("issue_comment_create", journal) if Site.has_blockchain? && @project.use_blockchain + end + end + end + end +end diff --git a/app/services/repositories/migrate_service.rb b/app/services/repositories/migrate_service.rb index 7cf1cb3e7..deb0e30d3 100644 --- a/app/services/repositories/migrate_service.rb +++ b/app/services/repositories/migrate_service.rb @@ -32,7 +32,8 @@ class Repositories::MigrateService < ApplicationService private: params[:hidden], mirror: wrapper_mirror || false, auth_username: params[:login], - auth_password: Base64.decode64(params[:password] || "") + auth_password: Base64.decode64(params[:password] || ""), + auth_token: params[:auth_token] } end diff --git a/app/services/sliding_window_rate_limiter.rb b/app/services/sliding_window_rate_limiter.rb new file mode 100644 index 000000000..a999345ef --- /dev/null +++ b/app/services/sliding_window_rate_limiter.rb @@ -0,0 +1,39 @@ + +class SlidingWindowRateLimiter + def initialize(user_id, rate, window_size) + @rate = rate # 请求速率限制(每秒的请求数) + @window_size = window_size # 时间窗口大小(秒) + @redis = $redis_cache + @key = "#{user_id}:SlidingWindow" + @current_timestamp = Time.now.to_f + end + + def allow_request + current_timestamp = Time.now.to_f + score = current_timestamp.to_i + start_time = current_timestamp - @window_size + + @redis.zremrangebyscore(@key, '-inf', start_time) + count = @redis.zcount(@key, '-inf', '+inf').to_i + + return false if count >= @rate + + @redis.zadd(@key, score, current_timestamp) + true + end +end + + +=begin + #测试通过 + + limiter = SlidingWindowRateLimiter.new(user_id,10, 1) # 设置请求速率限制为10次/秒,时间窗口大小为1秒 + 40.times do + if limiter.allow_request + puts "Allow" + else + puts "Reject" + end + end + +=end \ No newline at end of file diff --git a/app/services/token_bucket_rate_limiter.rb b/app/services/token_bucket_rate_limiter.rb new file mode 100644 index 000000000..c0d726b37 --- /dev/null +++ b/app/services/token_bucket_rate_limiter.rb @@ -0,0 +1,48 @@ +class TokenBucketRateLimiter + def initialize(user_id,rate, capacity) + @rate = rate # 令牌发放速率(每秒发放的令牌数) + @capacity = capacity # 令牌桶容量 + @redis = $redis_cache + @key = "#{user_id}:TokenBucket" + end + + def refill + now = Time.now.to_f * 1000 + tokens = $redis_cache.hget(@key, 'tokens') + timestamp = $redis_cache.hget(@key, 'timestamp') + + if tokens.nil? + tokens = @capacity + timestamp = now + else + tokens = [@capacity, tokens.to_i + (now - timestamp.to_f) * @rate / 1000].min + timestamp = now + end + + $redis_cache.hset(@key, 'tokens', tokens) + $redis_cache.hset(@key, 'timestamp', timestamp) + end + + def allow_request + refill + tokens = @redis.hget(@key, 'tokens') + if !tokens.nil? && tokens.to_i >= 1 + @redis.hset(@key, 'tokens', tokens.to_i - 1) + return true + end + false + end +end + +=begin + #测试通过 + limiter = TokenBucketRateLimiter.new(user_id,10, 40) # 设置令牌发放速率为10,令牌桶容量为40 + 30.times do + if limiter.allow_request + puts "Allow" + else + puts "Reject" + end + end + +=end \ No newline at end of file diff --git a/app/views/admins/feedbacks/_list.html.erb b/app/views/admins/feedbacks/_list.html.erb index 1b7b045ed..a630837f1 100644 --- a/app/views/admins/feedbacks/_list.html.erb +++ b/app/views/admins/feedbacks/_list.html.erb @@ -17,12 +17,8 @@序号 | +学生姓名 | +课题ID | +课题名称 | +邮件地址 | +视频地址 | +PR地址 | + 60 +考核阶段 | +白名单 | +检测状态 | +提交时间 | +
---|---|---|---|---|---|---|---|---|---|---|
<%= list_index_no((params[:page] || 1).to_i, index) %> | +<%= material.glcc_student.student_name %> | +<%= material.task_id %> | +<%= material.task.task_name %> | ++ + <%=material.glcc_student.mail.truncate(20) %> + + | + ++ + + <%= material.defence_video_url.nil? ? "" : material.defence_video_url.truncate(30) %> + + + | ++ + + <%= material.code_or_pr_url.nil? ? "" : material.code_or_pr_url.truncate(30) %> + + + | +<%= material.term == 1 ? "中期考核" : "结项考核"%> | +<%= material.white_list ? "是":"否" %> | +<%= material.state_to_html.blank?&&!material.white_list ? "通过" : material.state_to_html.html_safe %> | +<%= material.created_on.strftime("%Y-%m-%d %H:%M")%> | +
图片无法展示,图片已丢失
+ <%end%> +图片无法展示,图片已丢失
+ <%end%> +图片无法展示,图片已丢失
+ <%end%> +图片无法展示,图片已丢失
+ <%end%> +序号 | +昵称 | +审核状态 | +<%= sort_tag('创建于', name: 'created_at', path: admins_identity_verifications_path) %> | +操作 | +
---|---|---|---|---|
<%= list_index_no((params[:page] || 1).to_i, index) %> | ++ <%= link_to "/#{identity_verification.user.login}", target: '_blank' do %> + <%= overflow_hidden_span identity_verification.user.real_name, width: 100 %> + <% end %> + | +<%= display_text(identity_verification.state) %> | + +<%= display_text(identity_verification.created_at&.strftime('%Y-%m-%d %H:%M')) %> | ++ <%= link_to "#{ identity_verification.state == "待审核" ? '审核' : "查看"}", edit_admins_identity_verification_path(identity_verification), class: 'action' %> + | +
序号 | +建站工具 | +顺序 | +主题名 | +图片 | +仓库url | +操作 | +
---|---|---|---|---|---|---|
<%= list_index_no((params[:page] || 1).to_i, index) %> | +<%= theme.language_frame %> | +<%= theme.order_index %> | +<%= theme.name %> | ++ | <%= theme.clone_url %> | ++ <%= link_to "编辑", edit_admins_page_theme_path(theme), remote: true, class: "action" %> + <%= link_to "删除", admins_page_theme_path(theme), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %> + | +
序号 | +昵称 | +仓库 | +站点状态 | +站点名 | +站点标识 | +站点地址 | + +建站工具 | +主题 | +上次部署时间 | + + +<%= sort_tag('创建于', name: 'created_at', path: admins_site_pages_path) %> | +操作 | +
---|---|---|---|---|---|---|---|---|---|---|---|
<%= list_index_no((params[:page] || 1).to_i, index) %> | ++ <%= link_to "/#{site_page.user.login}", target: '_blank' do %> + <%= overflow_hidden_span site_page.user.real_name, width: 100 %> + <% end %> + | ++ <%= link_to "/#{site_page.user.login}/#{site_page.project.try(:identifier)}", target: '_blank' do %> + <%= overflow_hidden_span site_page.project.try(:name), width: 100 %> + <% end %> + | +<%= display_text(site_page.state == true ? "正常" : "已关闭") %> | +<%= display_text(site_page.site_name) %> | +<%= display_text(site_page.identifier) %> | ++ <%= link_to "#{site_page.url}", target: '_blank' do %> + <%= overflow_hidden_span site_page.url, width: 120 %> + <% end %> + | +<%= display_text(site_page.language_frame) %> | +<%= display_text(site_page.theme) %> | +<%= display_text(site_page.last_build_at&.strftime('%Y-%m-%d %H:%M')) %> | + +<%= display_text(site_page.created_at&.strftime('%Y-%m-%d %H:%M')) %> | + ++ <%= link_to "查看", edit_admins_site_page_path(site_page), class: 'action' %> + <%= link_to "删除", admins_site_page_path(site_page), method: :delete, data:{confirm: "确认删除吗,删除后站点将无法访问?"}, class: "action" %> + | +
+ 尊敬的<%=@name%>同学: +
+ ++ 您好!经过一个多月的开发,GLCC开源编程夏令营终于迎来中期考核。为了确保您能够顺利通过考核,现对您提交的PR链接进行检测,发现存在以下问题: +
+ ++ 您提交的PR链接的真实有效性对于后期的开发和奖金的发放至关重要,请您务必予以重视。请您尽快核查链接的有效性,并按照组委会要求提交中期考核材料。若确认链接无误,请忽略本邮件。 +
+ ++ 如有其他问题,请联系:glcc@ccf.org.cn +
+ ++ GLCC组委会 +
++ <%=Time.now.strftime('%Y年%m月%d日')%> +
+