diff --git a/Dockerfile b/Dockerfile index 0649c9227df..1fe4b3fe469 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,6 +52,7 @@ RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor < 1.0" gem "timescaledb", "~> 0.2" # Admin dashboard -gem "avo", "~> 3.2.1" +gem "avo", "~> 3.11" gem "pagy", "~> 8.4" gem "view_component", "~> 3.14" gem "pundit", "~> 2.4" gem "chartkick", "~> 5.1" gem "groupdate", "~> 6.2" +gem "dry-initializer", "~> 3.1" group :avo, optional: true do source "https://packager.dev/avo-hq/" do - gem "avo-advanced", "~> 3.2.0" + gem "avo-advanced", "~> 3.11" end end @@ -151,3 +152,5 @@ group :test do gem "minitest-reporters", "~> 1.7" gem "gem_server_conformance", "~> 0.1.4" end + +gem "avo_upgrade", "~> 0.1.1", group: :development diff --git a/Gemfile.lock b/Gemfile.lock index af1c99681a8..c2b8a89590d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,65 +1,63 @@ GEM remote: https://packager.dev/avo-hq/ specs: - avo-advanced (3.2.0) - avo (>= 3.2.1) - avo-dynamic_filters (>= 3.2.0) - avo-pro (>= 3.2.0) + avo-advanced (3.11.10) + avo (= 3.11.10) + avo-dynamic_filters (= 3.11.10) + avo-pro (= 3.11.10) zeitwerk (>= 2.6.12) - avo-dashboards (3.2.3) - avo (>= 3.2.1) + avo-dashboards (3.11.10) + avo (= 3.11.10) turbo-rails view_component (>= 3.7.0) zeitwerk (>= 2.6.12) - avo-dynamic_filters (3.2.0) - active_record_extended - avo (>= 3.2.1) - ransack (>= 4.1.1) + avo-dynamic_filters (3.11.10) + avo (= 3.11.10) + ransack (>= 4.2.0) view_component (>= 3.7.0) zeitwerk (>= 2.6.12) - avo-menu (3.2.0) - avo (>= 3.2.1) + avo-menu (3.11.10) + avo (= 3.11.10) docile - dry-initializer zeitwerk (>= 2.6.12) - avo-pro (3.2.2) - avo (>= 3.2.3) - avo-dashboards (>= 3.2.0) - avo-menu (>= 3.2.0) + avo-pro (3.11.10) + avo (= 3.11.10) + avo-dashboards (= 3.11.10) + avo-menu (= 3.11.10) zeitwerk (>= 2.6.12) GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) + actioncable (7.1.4) + actionpack (= 7.1.4) + activesupport (= 7.1.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionmailbox (7.1.4) + actionpack (= 7.1.4) + activejob (= 7.1.4) + activerecord (= 7.1.4) + activestorage (= 7.1.4) + activesupport (= 7.1.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3.4) - actionpack (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionmailer (7.1.4) + actionpack (= 7.1.4) + actionview (= 7.1.4) + activejob (= 7.1.4) + activesupport (= 7.1.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3.4) - actionview (= 7.1.3.4) - activesupport (= 7.1.3.4) + actionpack (7.1.4) + actionview (= 7.1.4) + activesupport (= 7.1.4) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -67,15 +65,15 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.4) - actionpack (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + actiontext (7.1.4) + actionpack (= 7.1.4) + activerecord (= 7.1.4) + activestorage (= 7.1.4) + activesupport (= 7.1.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.4) - activesupport (= 7.1.3.4) + actionview (7.1.4) + activesupport (= 7.1.4) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -83,25 +81,22 @@ GEM active_link_to (1.0.5) actionpack addressable - active_record_extended (3.3.0) - activerecord (>= 5.2, < 8.0.0) - pg (< 3.0) - activejob (7.1.3.4) - activesupport (= 7.1.3.4) + activejob (7.1.4) + activesupport (= 7.1.4) globalid (>= 0.3.6) - activemodel (7.1.3.4) - activesupport (= 7.1.3.4) - activerecord (7.1.3.4) - activemodel (= 7.1.3.4) - activesupport (= 7.1.3.4) + activemodel (7.1.4) + activesupport (= 7.1.4) + activerecord (7.1.4) + activemodel (= 7.1.4) + activesupport (= 7.1.4) timeout (>= 0.4.0) - activestorage (7.1.3.4) - actionpack (= 7.1.3.4) - activejob (= 7.1.3.4) - activerecord (= 7.1.3.4) - activesupport (= 7.1.3.4) + activestorage (7.1.4) + actionpack (= 7.1.4) + activejob (= 7.1.4) + activerecord (= 7.1.4) + activesupport (= 7.1.4) marcel (~> 1.0) - activesupport (7.1.3.4) + activesupport (7.1.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -126,22 +121,24 @@ GEM attr_required (1.0.2) autoprefixer-rails (10.4.19.0) execjs (~> 2) - avo (3.2.3) + avo (3.11.10) actionview (>= 6.1) active_link_to activerecord (>= 6.1) activesupport (>= 6.1) addressable docile - dry-initializer - httparty inline_svg + literal (~> 0.2) meta-tags - pagy - turbo-rails + pagy (>= 7.0.0) + turbo-rails (>= 2.0.0) turbo_power (>= 0.6.0) view_component (>= 3.7.0) zeitwerk (>= 2.6.12) + avo_upgrade (0.1.1) + rails (>= 6.0.0) + zeitwerk awrence (1.2.1) aws-eventstream (1.3.0) aws-partitions (1.966.0) @@ -331,10 +328,6 @@ GEM domain_name (~> 0.5) http-form_data (2.3.0) http_accept_language (2.1.1) - httparty (0.22.0) - csv - mini_mime (>= 1.0.0) - multi_xml (>= 0.5.2) i18n (1.14.5) concurrent-ruby (~> 1.0) importmap-rails (2.0.1) @@ -400,6 +393,7 @@ GEM listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) + literal (0.2.1) llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) rake (~> 13.0) @@ -462,7 +456,7 @@ GEM mutex_m (0.2.0) net-http (0.4.1) uri - net-imap (0.4.14) + net-imap (0.4.15) date net-protocol net-pop (0.1.2) @@ -471,7 +465,7 @@ GEM timeout net-smtp (0.5.0) net-protocol - nio4r (2.7.0) + nio4r (2.7.3) nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) @@ -575,20 +569,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.1.3.4) - actioncable (= 7.1.3.4) - actionmailbox (= 7.1.3.4) - actionmailer (= 7.1.3.4) - actionpack (= 7.1.3.4) - actiontext (= 7.1.3.4) - actionview (= 7.1.3.4) - activejob (= 7.1.3.4) - activemodel (= 7.1.3.4) - activerecord (= 7.1.3.4) - activestorage (= 7.1.3.4) - activesupport (= 7.1.3.4) + rails (7.1.4) + actioncable (= 7.1.4) + actionmailbox (= 7.1.4) + actionmailer (= 7.1.4) + actionpack (= 7.1.4) + actiontext (= 7.1.4) + actionview (= 7.1.4) + activejob (= 7.1.4) + activemodel (= 7.1.4) + activerecord (= 7.1.4) + activestorage (= 7.1.4) + activesupport (= 7.1.4) bundler (>= 1.15.0) - railties (= 7.1.3.4) + railties (= 7.1.4) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -612,9 +606,9 @@ GEM rack railties (>= 5.1) semantic_logger (~> 4.16) - railties (7.1.3.4) - actionpack (= 7.1.3.4) - activesupport (= 7.1.3.4) + railties (7.1.4) + actionpack (= 7.1.4) + activesupport (= 7.1.4) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -830,7 +824,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.36) - zeitwerk (2.6.17) + zeitwerk (2.6.18) zlib (3.1.1) PLATFORMS @@ -840,8 +834,9 @@ DEPENDENCIES aggregate_assertions (~> 0.2.0) amazing_print (~> 1.6) autoprefixer-rails (~> 10.4) - avo (~> 3.2.1) - avo-advanced (~> 3.2.0)! + avo (~> 3.11) + avo-advanced (~> 3.11)! + avo_upgrade (~> 0.1.1) aws-sdk-s3 (~> 1.159) aws-sdk-sqs (~> 1.80) bcrypt (~> 3.1) @@ -862,6 +857,7 @@ DEPENDENCIES discard (~> 1.3) dogstatsd-ruby (~> 5.5) dotenv-rails (~> 3.1) + dry-initializer (~> 3.1) factory_bot_rails (~> 6.4) faraday (~> 2.11) faraday-multipart (~> 1.0) @@ -954,19 +950,18 @@ DEPENDENCIES xml-simple (~> 1.1) CHECKSUMS - actioncable (7.1.3.4) sha256=787ba8651caaa93d5c161f0d1110105300974be65e89483071146fc42d4bd310 - actionmailbox (7.1.3.4) sha256=a3fd3019a44597e49ae18b4ed5c68e0f21c1d1b389bbcc10be357e205a83cad0 - actionmailer (7.1.3.4) sha256=1f196096740587b08ef935db8a672971f448cadb8299e3d9a7bc24088a2a0351 - actionpack (7.1.3.4) sha256=dcafc71bec6a975c3984a1ed8e698e2f9afeeb441c838766c16c29633705edd2 - actiontext (7.1.3.4) sha256=84964dae95a3c99819d42641084f21e28de502fcefa6efb9df3805d6c439b784 - actionview (7.1.3.4) sha256=41fcf5242dec11e100a0ba3d3717612c6534e8571c8a290a5b2a950aa58b615b + actioncable (7.1.4) sha256=8443dfe12129cf6d7c93b16a5f0be83bf0d3f686875d7ff5e1110c884c3e8fbc + actionmailbox (7.1.4) sha256=30be3b404290ef19c477aab19ee48cbcb6b409cc3f377f732c7b907998e6f36f + actionmailer (7.1.4) sha256=eae396a3f2de43c54f1d267ecc2e4593a0122f20e321dbee5c96ffcbbdfa4b25 + actionpack (7.1.4) sha256=f5f8879debbf0b1a73dcc60f91c975b7bed7ff87c873b5fa794acaa1f3b7e230 + actiontext (7.1.4) sha256=5d07bfe0d50cec80f55f71526aa67bbcc401f0ea6dcb611687119294b0da9b92 + actionview (7.1.4) sha256=c02bf0665edbfaf1616b41aad0ce8919820005226d4e78e56a998b6b32593953 active_link_to (1.0.5) sha256=4830847b3d14589df1e9fc62038ceec015257fce975ec1c2a77836c461b139ba - active_record_extended (3.3.0) sha256=6e1ba9bd09faa0d90337938251c595263770b485b2dc7753b172727bb2bf0ce6 - activejob (7.1.3.4) sha256=3f8aeef0fdfb2dd65f9a663828dbcc8ca187e70ef0c5a773c5fe4dd67e040f62 - activemodel (7.1.3.4) sha256=f4c838ea76dfca8967e433ac89603342ae20b65dd61366e62f07120a08e1ad72 - activerecord (7.1.3.4) sha256=784eeca4d6f23391d445552d6675a47c594555361c3b042108d29f0c7b9230f2 - activestorage (7.1.3.4) sha256=f2020ea0a77e105e480a9a15251c91d615eecb4b28a1a80968d6fb6a5dcb0a2e - activesupport (7.1.3.4) sha256=455bbc43d82e5ba20daa25f0888b80c9f7e2d80ca0cc96cea3e6acfec3e40309 + activejob (7.1.4) sha256=65f65a552aeb33f444fb57b9dc75ecc01693ef13ae410591c7a5f7763c3c0bf6 + activemodel (7.1.4) sha256=188d055afdd07d2f037d23403c939618ea0d7fa518a7de1b76324c2876d410b6 + activerecord (7.1.4) sha256=836d6dac137ec5bb71e7ab943f6eca97917c8a2968fa466b38920f4812642cdd + activestorage (7.1.4) sha256=23ebbb59fb9563f035ffa18d30b6bbc3a5d3f5cda004d19765f594db24f70b46 + activesupport (7.1.4) sha256=3a8e1a7ce5541ab2ffefaa390c40c89d7f54273dc671ed429614953cffd8a232 addressable (2.8.7) sha256=462986537cf3735ab5f3c0f557f14155d778f4b43ea4f485a9deb9c8f7c58232 aes_key_wrap (1.1.0) sha256=b935f4756b37375895db45669e79dfcdc0f7901e12d4e08974d5540c8e0776a5 aggregate_assertions (0.2.0) sha256=9bc51a48323a8e7b82f47cc38d48132817247345e5a8713686c9d65b25daca9e @@ -977,12 +972,13 @@ CHECKSUMS ast (2.4.2) sha256=1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12 attr_required (1.0.2) sha256=f0ebfc56b35e874f4d0ae799066dbc1f81efefe2364ca3803dc9ea6a4de6cb99 autoprefixer-rails (10.4.19.0) sha256=ccd21f47e5a07a581c7d239025e0d8d06a005825e96e06f72382d818fe665f4e - avo (3.2.3) sha256=632eae6803df6148804a2f87a8cf1a521a8778bc6ab2f82ba797907e30b82206 - avo-advanced (3.2.0) sha256=b10f224b01b14eaf5e23891470c9688dbab24af9fe39a03aa24dba36ebc26140 - avo-dashboards (3.2.3) sha256=f5bdc8f7650bf5f21a7e4caabfc476d6e71e73c4194bfc4549d1e17e1f93db6b - avo-dynamic_filters (3.2.0) sha256=ba0cb12d9e3eae86e5d91b1ce1f6e0090fd02aae58d8fa23ba1fd0a8cb941ff3 - avo-menu (3.2.0) sha256=9b45193993307265b07eee9a0874b92921476772610eb5171f99414e5059ec80 - avo-pro (3.2.2) sha256=dec357d60a1143cb1b7cc02c34bdc39ecdb6b12998b1d4097b0dd22b35c2affe + avo (3.11.10) sha256=5598770a18b36349ed9acc8b9aef4769b7f6301663cecc70a1a99cda76594fec + avo-advanced (3.11.10) sha256=5eec4d20fd5c148074897f9110a60a161311842ad60a1f6ee0080ab790bcf54f + avo-dashboards (3.11.10) sha256=741664c13985ba634639d5732312fb92e9422250beeef63005c24fe52fa0a3d5 + avo-dynamic_filters (3.11.10) sha256=bb74c6433bb027fe58ebc234d18681ad0afcaaa3914c0e95d036642d024a41f8 + avo-menu (3.11.10) sha256=d82fc939d978e267d1c38b2122035599c19248482e6479bef33eb3cd9f891666 + avo-pro (3.11.10) sha256=8cc8c1b04c44a530533d8d2042bb01a182c9a744e53db3915ee7cfbe31553a4d + avo_upgrade (0.1.1) sha256=8d841083b9956392f5c8fe195f25bec0d139e3646d276f8a59e66b7d2e9ebf30 awrence (1.2.1) sha256=dd1d214c12a91f449d1ef81d7ee3babc2816944e450752e7522c65521872483e aws-eventstream (1.3.0) sha256=f1434cc03ab2248756eb02cfa45e900e59a061d7fbdc4a9fd82a5dd23d796d3f aws-partitions (1.966.0) sha256=1402324c85cf16c3d53b1122ce961c913d4356d020c1bb1d845893c6fa8c51a2 @@ -1069,7 +1065,6 @@ CHECKSUMS http-cookie (1.0.6) sha256=7713d3196f21ff5ab0944011d7d4e619b62ec082374a52de2193ccfe78924044 http-form_data (2.3.0) sha256=cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3 http_accept_language (2.1.1) sha256=0043f0d55a148cf45b604dbdd197cb36437133e990016c68c892d49dbea31634 - httparty (0.22.0) sha256=78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c i18n (1.14.5) sha256=26dcbc05e364b57e27ab430148b3377bc413987d34cc042336271d8f42e9d1b9 importmap-rails (2.0.1) sha256=e739a6e70c09f797688c6983fa79567ec1edc9becc30d55b3f7cc897b1825586 inline_svg (1.9.0) sha256=f44c5e3d2e401fd619ad3047b7c8cee384517d855edb1d1fb1a248d3cae535d6 @@ -1093,6 +1088,7 @@ CHECKSUMS libdatadog (11.0.0.1.0) sha256=44779762b21149be5e17ce599dc2e89f6a3c89a99262293dfafd96ddb110f7f1 libddwaf (1.14.0.0.0) sha256=b91ea9675f7d79d1cd10dd6513e3706760ac442cb8902164fbcef79b7082a8fd listen (3.9.0) sha256=db9e4424e0e5834480385197c139cb6b0ae0ef28cc13310cfd1ca78377d59c67 + literal (0.2.1) sha256=7544725886486ce6ae701fea1ea23bb7955ef218ef109f91ad4414f3b7921261 llhttp-ffi (0.5.0) sha256=496f40ad44bcbf99de02da1f26b1ad64e6593cd487b931508a86228e2a3af0fa local_time (3.0.2) sha256=cb8abb2d56726ae285d00b0bd7f4c34bafc38c0c1cbc70ddc28f3a5661168d9d logger (1.6.0) sha256=0ab7c120262dd8de2a18cb8d377f1f318cbe98535160a508af9e7710ff43ef3e @@ -1119,11 +1115,11 @@ CHECKSUMS multipart-post (2.4.1) sha256=9872d03a8e552020ca096adadbf5e3cb1cd1cdd6acd3c161136b8a5737cdb4a8 mutex_m (0.2.0) sha256=b6ef0c6c842ede846f2ec0ade9e266b1a9dac0bc151682b04835e8ebd54840d5 net-http (0.4.1) sha256=a96efc5ea18bcb9715e24dda4159d10f67ff0345c8a980d04630028055b2c282 - net-imap (0.4.14) sha256=a2184b3f09a4f7ca27998d113fd6df8cd0dd56b91e5bf0d6387b8350bb438065 + net-imap (0.4.15) sha256=e468121d50cfcf82b7bbcee823d352bbb62ba8add963daa0c08d21680d83b53d net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 net-smtp (0.5.0) sha256=5fc0415e6ea1cc0b3dfea7270438ec22b278ca8d524986a3ae4e5ae8d087b42a - nio4r (2.7.0) sha256=9586a685eca8246d6406e712a525e705d15bb88f709d78fc3f141e864df97276 + nio4r (2.7.3) sha256=54b94cdd4b8f9dc39aaad5f699e97afae13efb44f2b180a6e724df76105ff604 nokogiri (1.16.7) sha256=f819cbfdfb0a7b19c9c52c6f2ca63df0e58a6125f4f139707b586b9511d7fe95 oauth2 (2.0.9) sha256=b21f9defcf52dc1610e0dfab4c868342173dcd707fd15c777d9f4f04e153f7fb observer (0.1.2) sha256=d8a3107131ba661138d748e7be3dbafc0d82e732fffba9fccb3d7829880950ac @@ -1165,14 +1161,14 @@ CHECKSUMS rack-session (2.0.0) sha256=db04b2063e180369192a9046b4559af311990af38c6a93d4c600cee4eb6d4e81 rack-test (2.1.0) sha256=0c61fc61904049d691922ea4bb99e28004ed3f43aa5cfd495024cc345f125dfb rackup (2.1.0) sha256=6ecb884a581990332e45ee17bdfdc14ccbee46c2f710ae1566019907869a6c4d - rails (7.1.3.4) sha256=3a7fca9df74ee641dc1e89b8302ac6d03f22883de771e786a0e9f3094e5aa6ad + rails (7.1.4) sha256=dfcf9e78d26db70320b99958e7ee8957db9cee5969279d449b925cdab18cc51e rails-controller-testing (1.0.5) sha256=741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94 rails-dom-testing (2.2.0) sha256=e515712e48df1f687a1d7c380fd7b07b8558faa26464474da64183a7426fa93b rails-erd (1.7.2) sha256=0b17d0fba25d319d8da8af7a3e5e2149d02d6187cc7351e8be43423f07c48bcd rails-html-sanitizer (1.6.0) sha256=86e9f19d2e6748890dcc2633c8945ca45baa08a1df9d8c215ce17b3b0afaa4de rails-i18n (7.0.9) sha256=c184db80a7c7bf21c14e0e400fe9e27c4c20312f019aaff5b364a82858dc1369 rails_semantic_logger (4.17.0) sha256=cc10cca01491736596cd5ab40b52b3bbf98338d9d1f5a7916b2be10231615047 - railties (7.1.3.4) sha256=6c6049f3a788669d94f95c7bf6378204ae94098567cc25237e3c73dac4a21afc + railties (7.1.4) sha256=54395f2753366699e54417aea67d8b3c0eefd994de2f4152d364a400de634a5a rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.2.1) sha256=46cb38dae65d7d74b6020a4ac9d48afed8eb8149c040eccf0523bec91907059d ransack (4.2.1) sha256=e0f688c6ef35abe0bad3cf5afc1b050f36a819bdd56eb454c955c63cdd1bef40 @@ -1262,7 +1258,7 @@ CHECKSUMS xml-simple (1.1.9) sha256=d21131e519c86f1a5bc2b6d2d57d46e6998e47f18ed249b25cad86433dbd695d xpath (3.2.0) sha256=6dfda79d91bb3b949b947ecc5919f042ef2f399b904013eb3ef6d20dd3a4082e yard (0.9.36) sha256=5505736c1b00c926f71053a606ab75f02070c5960d0778b901fe9d8b0a470be4 - zeitwerk (2.6.17) sha256=0895160c92ea5ffc88c38556fbbca798b61164daca97461ab5f47b8a07fb2aac + zeitwerk (2.6.18) sha256=bd2d213996ff7b3b364cd342a585fbee9797dbc1c0c6d868dc4150cc75739781 zlib (3.1.1) sha256=f61bb03139bbe256c36ba99ef9fece1fb223e9034ed9e5fa3ddb1588d99abc71 RUBY VERSION diff --git a/app/avo/actions/add_owner.rb b/app/avo/actions/add_owner.rb index bd98d1b8993..b6f49f016e3 100644 --- a/app/avo/actions/add_owner.rb +++ b/app/avo/actions/add_owner.rb @@ -1,10 +1,12 @@ -class AddOwner < BaseAction +class Avo::Actions::AddOwner < Avo::Actions::ApplicationAction self.name = "Add owner" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show } - field :owner, as: :select_record, searchable: true, name: "New owner", use_resource: UserResource + def fields + field :owner, as: :select_record, searchable: true, name: "New owner", use_resource: Avo::Resources::User + end self.message = lambda { "Are you sure you would like to add an owner to #{record.name}?" @@ -12,7 +14,7 @@ class AddOwner < BaseAction self.confirm_button_label = "Add owner" - class ActionHandler < ActionHandler + class ActionHandler < Avo::Actions::ActionHandler set_callback :handle, :before do @owner = fields[:owner] error "Must specify a valid user to add as owner" if @owner.blank? @@ -22,16 +24,16 @@ class ActionHandler < ActionHandler error "Cannot add #{@owner.name} as an owner since they are unconfirmed" if @owner.unconfirmed? end - def do_handle_model(rubygem) + def do_handle_record(rubygem) @rubygem = rubygem super end - set_callback :handle_model, :before do + set_callback :handle_record, :before do error "Cannot add #{@owner.name} as an owner since they are already an owner of #{@rubygem.name}" if @owner.rubygems.include?(@rubygem) end - def handle_model(rubygem) + def handle_record(rubygem) authorizer = User.security_user rubygem.ownerships.create!(user: @owner, authorizer: authorizer, confirmed_at: Time.current) succeed "Added #{@owner.name} to #{@rubygem.name}" diff --git a/app/avo/actions/base_action.rb b/app/avo/actions/application_action.rb similarity index 66% rename from app/avo/actions/base_action.rb rename to app/avo/actions/application_action.rb index 4e985aef5b2..468e8f65e53 100644 --- a/app/avo/actions/base_action.rb +++ b/app/avo/actions/application_action.rb @@ -1,17 +1,19 @@ -class BaseAction < Avo::BaseAction +class Avo::Actions::ApplicationAction < Avo::BaseAction include SemanticLogger::Loggable - field :comment, as: :textarea, required: true, - help: "A comment explaining why this action was taken.
Will be saved in the audit log.
Must be more than 10 characters." - - def self.inherited(base) - super - base.items_holder = Avo::ItemsHolder.new - base.items_holder.instance_variable_get(:@items).replace items_holder.instance_variable_get(:@items).deep_dup - base.items_holder.invalid_fields.replace items_holder.invalid_fields.deep_dup + def fields + field :comment, as: :textarea, required: true, + help: "A comment explaining why this action was taken.
Will be saved in the audit log.
Must be more than 10 characters." end - class ActionHandler + # def self.inherited(base) + # super + # base.items_holder = Avo::Resources::Items::Holder.new + # base.items_holder.instance_variable_get(:@items).replace items_holder.instance_variable_get(:@items).deep_dup + # base.items_holder.invalid_fields.replace items_holder.invalid_fields.deep_dup + # end + + class Avo::Actions::ActionHandler include Auditable include SemanticLogger::Loggable @@ -20,7 +22,7 @@ class ActionHandler result_lambda.call target.errored? } - define_callbacks :handle_model, terminator: lambda { |target, result_lambda| + define_callbacks :handle_record, terminator: lambda { |target, result_lambda| result_lambda.call target.errored? } @@ -35,9 +37,9 @@ def initialize( # rubocop:disable Metrics/ParameterLists arguments:, resource:, action:, - models: nil + records: nil ) - @models = models + @records = records @fields = fields @current_user = current_user @arguments = arguments @@ -46,7 +48,7 @@ def initialize( # rubocop:disable Metrics/ParameterLists @action = action end - attr_reader :models, :fields, :current_user, :arguments, :resource + attr_reader :records, :fields, :current_user, :arguments, :resource delegate :error, :avo, :keep_modal_open, :redirect_to, :inform, :action_name, :succeed, :logger, to: :@action @@ -72,9 +74,9 @@ def do_handle keep_modal_open if errored? end - def do_handle_model(model) - run_callbacks :handle_model do - handle_model(model) + def do_handle_record(record) + run_callbacks :handle_record do + handle_record(record) end end @@ -89,7 +91,7 @@ def do_handle_standalone action: action_name, fields:, arguments:, - models: + records: ) do run_callbacks :handle_standalone do handle_standalone @@ -99,17 +101,17 @@ def do_handle_standalone end def handle - return do_handle_standalone if models.nil? - models.each do |model| + return do_handle_standalone if records.nil? + records.each do |record| _, audit = in_audited_transaction( - auditable: model, + auditable: record, admin_github_user: current_user, action: action_name, fields:, arguments:, - models: + records: ) do - do_handle_model(model) + do_handle_record(record) end redirect_to avo.resources_audit_path(audit) end @@ -117,7 +119,7 @@ def handle end def handle(**args) - "#{self.class}::ActionHandler" + "#{self.class}::Avo::Actions::ActionHandler" .constantize .new(**args, arguments:, action: self) .do_handle diff --git a/app/avo/actions/block_user.rb b/app/avo/actions/block_user.rb index d73eb3fb7f8..2ec8e9ca525 100644 --- a/app/avo/actions/block_user.rb +++ b/app/avo/actions/block_user.rb @@ -1,4 +1,4 @@ -class BlockUser < BaseAction +class Avo::Actions::BlockUser < Avo::Actions::ApplicationAction self.name = "Block User" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -10,8 +10,8 @@ class BlockUser < BaseAction self.confirm_button_label = "Block User" - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.block! end end diff --git a/app/avo/actions/change_user_email.rb b/app/avo/actions/change_user_email.rb index 949a0f82feb..c7cfb87b5f8 100644 --- a/app/avo/actions/change_user_email.rb +++ b/app/avo/actions/change_user_email.rb @@ -1,5 +1,7 @@ -class ChangeUserEmail < BaseAction - field :from_email, name: "Email", as: :text, required: true +class Avo::Actions::ChangeUserEmail < Avo::Actions::ApplicationAction + def fields + field :from_email, name: "Email", as: :text, required: true + end self.name = "Change User Email" self.visible = lambda { @@ -8,8 +10,8 @@ class ChangeUserEmail < BaseAction self.confirm_button_label = "Change User Email" - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.email = fields["from_email"] user.email_confirmed = false user.generate_confirmation_token diff --git a/app/avo/actions/create_user.rb b/app/avo/actions/create_user.rb index 8abd11d3969..ced6228c678 100644 --- a/app/avo/actions/create_user.rb +++ b/app/avo/actions/create_user.rb @@ -1,6 +1,4 @@ -class CreateUser < BaseAction - field :email, name: "Email", as: :text, required: true - +class Avo::Actions::CreateUser < Avo::Actions::ApplicationAction self.name = "Create User" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :index && !Rails.env.production? @@ -9,7 +7,11 @@ class CreateUser < BaseAction self.confirm_button_label = "Create User" - class ActionHandler < ActionHandler + def fields + field :email, name: "Email", as: :text, required: true + end + + class ActionHandler < Avo::Actions::ActionHandler def handle_standalone user = User.new( email: fields["email"], diff --git a/app/avo/actions/delete_webhook.rb b/app/avo/actions/delete_webhook.rb index 4a696fbc5c8..da6959c8ed3 100644 --- a/app/avo/actions/delete_webhook.rb +++ b/app/avo/actions/delete_webhook.rb @@ -1,4 +1,4 @@ -class DeleteWebhook < BaseAction +class Avo::Actions::DeleteWebhook < Avo::Actions::ApplicationAction self.name = "Delete Webhook" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -10,8 +10,8 @@ class DeleteWebhook < BaseAction self.confirm_button_label = "Delete Webhook" - class ActionHandler < ActionHandler - def handle_model(webhook) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(webhook) webhook.destroy! WebHooksMailer.webhook_deleted(webhook.user_id, webhook.rubygem_id, webhook.url, webhook.failure_count).deliver_later end diff --git a/app/avo/actions/refresh_oidc_provider.rb b/app/avo/actions/refresh_oidc_provider.rb index c53e53d766f..eac8c960589 100644 --- a/app/avo/actions/refresh_oidc_provider.rb +++ b/app/avo/actions/refresh_oidc_provider.rb @@ -1,4 +1,4 @@ -class RefreshOIDCProvider < BaseAction +class Avo::Actions::RefreshOIDCProvider < Avo::Actions::ApplicationAction self.name = "Refresh OIDC Provider" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -10,8 +10,8 @@ class RefreshOIDCProvider < BaseAction self.confirm_button_label = "Refresh" - class ActionHandler < ActionHandler - def handle_model(provider) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(provider) RefreshOIDCProviderJob.perform_now(provider:) end end diff --git a/app/avo/actions/release_reserved_namespace.rb b/app/avo/actions/release_reserved_namespace.rb index 1cbbe8b793c..8ae227a433f 100644 --- a/app/avo/actions/release_reserved_namespace.rb +++ b/app/avo/actions/release_reserved_namespace.rb @@ -1,4 +1,4 @@ -class ReleaseReservedNamespace < BaseAction +class Avo::Actions::ReleaseReservedNamespace < Avo::Actions::ApplicationAction self.name = "Release reserved namespace" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -10,8 +10,8 @@ class ReleaseReservedNamespace < BaseAction self.confirm_button_label = "Release namespace" - class ActionHandler < ActionHandler - def handle_model(rubygem) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(rubygem) rubygem.release_reserved_namespace! end end diff --git a/app/avo/actions/reset_api_key.rb b/app/avo/actions/reset_api_key.rb index 9f5240c4958..4c43f04a287 100644 --- a/app/avo/actions/reset_api_key.rb +++ b/app/avo/actions/reset_api_key.rb @@ -1,4 +1,4 @@ -class ResetApiKey < BaseAction +class Avo::Actions::ResetApiKey < Avo::Actions::ApplicationAction self.name = "Reset Api Key" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -8,15 +8,17 @@ class ResetApiKey < BaseAction } self.confirm_button_label = "Reset Api Key" - field :template, as: :select, - options: { - "Public Gem": :public_gem_reset_api_key, - Honeycomb: :honeycomb_reset_api_key - }, - help: "Select mailer template" + def fields + field :template, as: :select, + options: { + "Public Gem": :public_gem_reset_api_key, + Honeycomb: :honeycomb_reset_api_key + }, + help: "Select mailer template" + end - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.reset_api_key! Mailer.reset_api_key(user, fields["template"]).deliver_later diff --git a/app/avo/actions/reset_user_2fa.rb b/app/avo/actions/reset_user_2fa.rb index 03e19a1d518..c775f717593 100644 --- a/app/avo/actions/reset_user_2fa.rb +++ b/app/avo/actions/reset_user_2fa.rb @@ -1,4 +1,4 @@ -class ResetUser2fa < BaseAction +class Avo::Actions::ResetUser2fa < Avo::Actions::ApplicationAction self.name = "Reset User 2FA" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -10,8 +10,8 @@ class ResetUser2fa < BaseAction self.confirm_button_label = "Reset MFA" - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.disable_totp! user.password = SecureRandom.hex(20).encode("UTF-8") user.save! diff --git a/app/avo/actions/restore_version.rb b/app/avo/actions/restore_version.rb index 2a5bf7f250f..bfb80bdba34 100644 --- a/app/avo/actions/restore_version.rb +++ b/app/avo/actions/restore_version.rb @@ -1,17 +1,17 @@ -class RestoreVersion < BaseAction +class Avo::Actions::RestoreVersion < Avo::Actions::ApplicationAction self.name = "Restore version" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show && - resource.model.deletion.present? + resource.record.deletion.present? } self.message = lambda { "Are you sure you would like to restore #{record.slug} with " } self.confirm_button_label = "Restore version" - class ActionHandler < ActionHandler - def handle_model(version) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(version) version.deletion&.restore! end end diff --git a/app/avo/actions/upload_info_file.rb b/app/avo/actions/upload_info_file.rb index 38740af0a4f..264dd083ac9 100644 --- a/app/avo/actions/upload_info_file.rb +++ b/app/avo/actions/upload_info_file.rb @@ -1,12 +1,12 @@ -class UploadInfoFile < BaseAction +class Avo::Actions::UploadInfoFile < Avo::Actions::ApplicationAction self.name = "Upload Info File" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show } self.confirm_button_label = "Upload" - class ActionHandler < ActionHandler - def handle_model(rubygem) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(rubygem) UploadInfoFileJob.perform_later(rubygem_name: rubygem.name) succeed("Upload job scheduled") diff --git a/app/avo/actions/upload_names_file.rb b/app/avo/actions/upload_names_file.rb index 1ab53b4ce95..c9eac66a398 100644 --- a/app/avo/actions/upload_names_file.rb +++ b/app/avo/actions/upload_names_file.rb @@ -1,4 +1,4 @@ -class UploadNamesFile < BaseAction +class Avo::Actions::UploadNamesFile < Avo::Actions::ApplicationAction self.name = "Upload Names File" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :index @@ -6,7 +6,7 @@ class UploadNamesFile < BaseAction self.standalone = true self.confirm_button_label = "Upload" - class ActionHandler < ActionHandler + class ActionHandler < Avo::Actions::ActionHandler def handle_standalone UploadNamesFileJob.perform_later diff --git a/app/avo/actions/upload_versions_file.rb b/app/avo/actions/upload_versions_file.rb index ee5f700a02a..7a14e02a864 100644 --- a/app/avo/actions/upload_versions_file.rb +++ b/app/avo/actions/upload_versions_file.rb @@ -1,4 +1,4 @@ -class UploadVersionsFile < BaseAction +class Avo::Actions::UploadVersionsFile < Avo::Actions::ApplicationAction self.name = "Upload Versions File" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :index @@ -6,7 +6,7 @@ class UploadVersionsFile < BaseAction self.standalone = true self.confirm_button_label = "Upload" - class ActionHandler < ActionHandler + class ActionHandler < Avo::Actions::ActionHandler def handle_standalone UploadVersionsFileJob.perform_later diff --git a/app/avo/actions/version_after_write.rb b/app/avo/actions/version_after_write.rb index 94490970847..cfbe40a9933 100644 --- a/app/avo/actions/version_after_write.rb +++ b/app/avo/actions/version_after_write.rb @@ -1,9 +1,9 @@ -class VersionAfterWrite < BaseAction +class Avo::Actions::VersionAfterWrite < Avo::Actions::ApplicationAction self.name = "Run version post-write job" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show && - resource.model.deletion.blank? + resource.record.deletion.blank? } self.message = lambda { @@ -12,8 +12,8 @@ class VersionAfterWrite < BaseAction self.confirm_button_label = "Run Job" - class ActionHandler < ActionHandler - def handle_model(version) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(version) AfterVersionWriteJob.new(version: version).perform(version: version) end end diff --git a/app/avo/actions/yank_rubygem.rb b/app/avo/actions/yank_rubygem.rb index 21c9771ef37..43b14b47344 100644 --- a/app/avo/actions/yank_rubygem.rb +++ b/app/avo/actions/yank_rubygem.rb @@ -1,17 +1,19 @@ -class YankRubygem < BaseAction +class Avo::Actions::YankRubygem < Avo::Actions::ApplicationAction OPTION_ALL = "All".freeze - field :version, as: :select, - options: lambda { |model:, resource:, view:, field:| # rubocop:disable Lint/UnusedBlockArgument - [OPTION_ALL] + model.versions.indexed.pluck(:number, :id) - }, - help: "Select Version which needs to be yanked." + def fields + field :version, as: :select, + options: lambda { |record:, resource:, view:, field:| # rubocop:disable Lint/UnusedBlockArgument + [OPTION_ALL] + record.versions.indexed.pluck(:number, :id) + }, + help: "Select Version which needs to be yanked." + end self.name = "Yank Rubygem" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show && - resource.model.versions.indexed.present? + resource.record.versions.indexed.present? } self.message = lambda { @@ -20,8 +22,8 @@ class YankRubygem < BaseAction self.confirm_button_label = "Yank Rubygem" - class ActionHandler < ActionHandler - def handle_model(rubygem) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(rubygem) version_id = fields["version"] version_id_to_yank = version_id if version_id != OPTION_ALL diff --git a/app/avo/actions/yank_rubygems_for_user.rb b/app/avo/actions/yank_rubygems_for_user.rb index d6f5e00e334..ba3edb0b157 100644 --- a/app/avo/actions/yank_rubygems_for_user.rb +++ b/app/avo/actions/yank_rubygems_for_user.rb @@ -1,9 +1,9 @@ -class YankRubygemsForUser < BaseAction +class Avo::Actions::YankRubygemsForUser < Avo::Actions::ApplicationAction self.name = "Yank all Rubygems" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show && - resource.model.rubygems.present? + resource.record.rubygems.present? } self.message = lambda { @@ -12,8 +12,8 @@ class YankRubygemsForUser < BaseAction self.confirm_button_label = "Yank all Rubygems" - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.rubygems.find_each do |rubygem| rubygem.yank_versions!(force: true) end diff --git a/app/avo/actions/yank_user.rb b/app/avo/actions/yank_user.rb index 1f4f34acdf8..9a0612048cf 100644 --- a/app/avo/actions/yank_user.rb +++ b/app/avo/actions/yank_user.rb @@ -1,4 +1,4 @@ -class YankUser < BaseAction +class Avo::Actions::YankUser < Avo::Actions::ApplicationAction self.name = "Yank User" self.visible = lambda { current_user.team_member?("rubygems-org") && view == :show @@ -8,8 +8,8 @@ class YankUser < BaseAction } self.confirm_button_label = "Yank User" - class ActionHandler < ActionHandler - def handle_model(user) + class ActionHandler < Avo::Actions::ActionHandler + def handle_record(user) user.rubygems.find_each do |rubygem| rubygem.yank_versions!(force: true) end diff --git a/app/avo/cards/dashboard_welcome_card.rb b/app/avo/cards/dashboard_welcome_card.rb index 8cbadb73c47..e5d37e51490 100644 --- a/app/avo/cards/dashboard_welcome_card.rb +++ b/app/avo/cards/dashboard_welcome_card.rb @@ -1,4 +1,4 @@ -class DashboardWelcomeCard < Avo::Dashboards::PartialCard +class Avo::Cards::DashboardWelcomeCard < Avo::Cards::PartialCard self.id = "dashboard_welcome_card" self.label = "Welcome to the RubyGems.org admin dashboard!" self.partial = "avo/cards/dashboard_welcome_card" diff --git a/app/avo/cards/pushes_chart.rb b/app/avo/cards/pushes_chart.rb index 5d45743df0b..523970c762f 100644 --- a/app/avo/cards/pushes_chart.rb +++ b/app/avo/cards/pushes_chart.rb @@ -1,4 +1,4 @@ -class PushesChart < Avo::Dashboards::ChartkickCard +class Avo::Cards::PushesChart < Avo::Cards::ChartkickCard self.id = "pushes_chart" self.label = "Pushes by day" self.chart_type = :line_chart diff --git a/app/avo/cards/rubygems_metric.rb b/app/avo/cards/rubygems_metric.rb index 03f9dfc57a6..cd74a871bed 100644 --- a/app/avo/cards/rubygems_metric.rb +++ b/app/avo/cards/rubygems_metric.rb @@ -1,4 +1,4 @@ -class RubygemsMetric < Avo::Dashboards::MetricCard +class Avo::Cards::RubygemsMetric < Avo::Cards::MetricCard self.id = "rubygems_metric" self.label = "RubyGems " self.cols = 2 diff --git a/app/avo/cards/users_metric.rb b/app/avo/cards/users_metric.rb index 18033d49463..e9eb71941f2 100644 --- a/app/avo/cards/users_metric.rb +++ b/app/avo/cards/users_metric.rb @@ -1,4 +1,4 @@ -class UsersMetric < Avo::Dashboards::MetricCard +class Avo::Cards::UsersMetric < Avo::Cards::MetricCard self.id = "users_metric" self.label = "Total users" self.cols = 2 diff --git a/app/avo/cards/versions_metric.rb b/app/avo/cards/versions_metric.rb index fefa912a30f..0c245831f40 100644 --- a/app/avo/cards/versions_metric.rb +++ b/app/avo/cards/versions_metric.rb @@ -1,4 +1,4 @@ -class VersionsMetric < Avo::Dashboards::MetricCard +class Avo::Cards::VersionsMetric < Avo::Cards::MetricCard self.id = "versions_metric" self.label = "Versions pushed" diff --git a/app/avo/dashboards/dashy.rb b/app/avo/dashboards/dashy.rb index 3a5ef54376c..08214f75084 100644 --- a/app/avo/dashboards/dashy.rb +++ b/app/avo/dashboards/dashy.rb @@ -1,21 +1,21 @@ -class Dashy < Avo::Dashboards::BaseDashboard +class Avo::Dashboards::Dashy < Avo::Dashboards::BaseDashboard self.id = "dashy" - self.name = "Dashy" + self.name = "Avo::Dashboards::Dashy" self.grid_cols = 6 self.visible = lambda { current_user.team_member?("rubygems-org") } # cards go here - card DashboardWelcomeCard + card Avo::Cards::DashboardWelcomeCard divider label: "Metrics" - card UsersMetric - card VersionsMetric - card RubygemsMetric + card Avo::Cards::UsersMetric + card Avo::Cards::VersionsMetric + card Avo::Cards::RubygemsMetric divider label: "Charts" - card PushesChart + card Avo::Cards::PushesChart end diff --git a/app/avo/fields/array_of_field.rb b/app/avo/fields/array_of_field.rb index 7688f1662ed..d86dba064d2 100644 --- a/app/avo/fields/array_of_field.rb +++ b/app/avo/fields/array_of_field.rb @@ -1,9 +1,9 @@ -class ArrayOfField < Avo::Fields::BaseField +class Avo::Fields::ArrayOfField < Avo::Fields::BaseField def initialize(name, field:, field_options: {}, **args, &block) super(name, **args, &nil) @make_field = lambda do |id:, index: nil, value: nil| - items_holder = Avo::ItemsHolder.new + items_holder = Avo::Resources::Items::Holder.new items_holder.field(id, name: index&.to_s || self.name, as: field, required: -> { false }, value:, **field_options, &block) items_holder.items.sole.hydrate(view:, resource:) end diff --git a/app/avo/fields/audited_changes_field.rb b/app/avo/fields/audited_changes_field.rb index 4d4398abcb3..3f4e8b522bb 100644 --- a/app/avo/fields/audited_changes_field.rb +++ b/app/avo/fields/audited_changes_field.rb @@ -1,2 +1,2 @@ -class AuditedChangesField < Avo::Fields::BaseField +class Avo::Fields::AuditedChangesField < Avo::Fields::BaseField end diff --git a/app/avo/fields/json_viewer_field.rb b/app/avo/fields/json_viewer_field.rb index df4d52e45d3..aedb7030e5f 100644 --- a/app/avo/fields/json_viewer_field.rb +++ b/app/avo/fields/json_viewer_field.rb @@ -1,4 +1,4 @@ -class JsonViewerField < Avo::Fields::CodeField +class Avo::Fields::JsonViewerField < Avo::Fields::CodeField def initialize(name, **args, &) super(name, **args, language: :javascript, line_wrapping: true, &) end diff --git a/app/avo/fields/nested_field.rb b/app/avo/fields/nested_field.rb index 769216a026a..c0078d70892 100644 --- a/app/avo/fields/nested_field.rb +++ b/app/avo/fields/nested_field.rb @@ -1,8 +1,8 @@ -class NestedField < Avo::Fields::BaseField - include Avo::Concerns::HasFields +class Avo::Fields::NestedField < Avo::Fields::BaseField + include Avo::Concerns::HasItems def initialize(name, stacked: true, **args, &block) - @items_holder = Avo::ItemsHolder.new + @items_holder = Avo::Resources::Items::Holder.new hide_on :index super(name, stacked:, **args, &nil) instance_exec(&block) if block diff --git a/app/avo/fields/select_record_field.rb b/app/avo/fields/select_record_field.rb index 83da8985919..b5b2a25a45e 100644 --- a/app/avo/fields/select_record_field.rb +++ b/app/avo/fields/select_record_field.rb @@ -1,4 +1,4 @@ -class SelectRecordField < Avo::Fields::BelongsToField +class Avo::Fields::SelectRecordField < Avo::Fields::BelongsToField def foreign_key id end diff --git a/app/avo/filters/email_filter.rb b/app/avo/filters/email_filter.rb index 2a3375c86c5..2cbc9e19912 100644 --- a/app/avo/filters/email_filter.rb +++ b/app/avo/filters/email_filter.rb @@ -1,4 +1,4 @@ -class EmailFilter < Avo::Filters::TextFilter +class Avo::Filters::EmailFilter < Avo::Filters::TextFilter self.name = "Email filter" self.button_label = "Filter by email" diff --git a/app/avo/filters/scope_boolean_filter.rb b/app/avo/filters/scope_boolean_filter.rb index 6addbbcb400..67543347576 100644 --- a/app/avo/filters/scope_boolean_filter.rb +++ b/app/avo/filters/scope_boolean_filter.rb @@ -1,4 +1,4 @@ -class ScopeBooleanFilter < Avo::Filters::BooleanFilter +class Avo::Filters::ScopeBooleanFilter < Avo::Filters::BooleanFilter def name arguments.fetch(:name) { self.class.to_s.demodulize.underscore.sub(/_filter$/, "").titleize } end diff --git a/app/avo/resources/admin_github_user.rb b/app/avo/resources/admin_github_user.rb new file mode 100644 index 00000000000..5ace30069df --- /dev/null +++ b/app/avo/resources/admin_github_user.rb @@ -0,0 +1,34 @@ +class Avo::Resources::AdminGitHubUser < Avo::BaseResource + self.title = :login + self.includes = [] + self.model_class = ::Admin::GitHubUser + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("login LIKE ?", "%#{params[:q]}%") + } + end + + self.description = "GitHub users that have authenticated via the admin OAuth flow." + + def fields + field :id, as: :id + + field :is_admin, as: :boolean, readonly: true + field :login, as: :text, readonly: true, + as_html: true, + format_using: -> { link_to value, "https://github.com/#{value}" } + field :avatar_url, as: :external_image, name: "Avatar", readonly: true + field :github_id, as: :text, readonly: true + field :oauth_token, as: :text, visible: -> { false } + + field :details, as: :heading + + field :teams, as: :tags, readonly: true, format_using: -> { value.pluck(:slug) } + + field :info_data, + as: :code, readonly: true, language: :javascript, + format_using: -> { JSON.pretty_generate value } + + field :audits, as: :has_many + end +end diff --git a/app/avo/resources/admin_github_user_resource.rb b/app/avo/resources/admin_github_user_resource.rb deleted file mode 100644 index 65a1e6c79e3..00000000000 --- a/app/avo/resources/admin_github_user_resource.rb +++ /dev/null @@ -1,31 +0,0 @@ -class AdminGitHubUserResource < Avo::BaseResource - self.title = :login - self.includes = [] - self.model_class = ::Admin::GitHubUser - self.authorization_policy = ::Admin::GitHubUserPolicy - self.search_query = lambda { - scope.where("login LIKE ?", "%#{params[:q]}%") - } - - self.description = "GitHub users that have authenticated via the admin OAuth flow." - - field :id, as: :id - - field :is_admin, as: :boolean, readonly: true - field :login, as: :text, readonly: true, - as_html: true, - format_using: -> { link_to value, "https://github.com/#{value}" } - field :avatar_url, as: :external_image, name: "Avatar", readonly: true - field :github_id, as: :text, readonly: true - field :oauth_token, as: :text, visible: ->(resource:) { false } # rubocop:disable Lint/UnusedBlockArgument - - heading "Details" - - field :teams, as: :tags, readonly: true, format_using: -> { value.pluck(:slug) } - - field :info_data, - as: :code, readonly: true, language: :javascript, - format_using: -> { JSON.pretty_generate value } - - field :audits, as: :has_many -end diff --git a/app/avo/resources/api_key.rb b/app/avo/resources/api_key.rb new file mode 100644 index 00000000000..c3c2251565e --- /dev/null +++ b/app/avo/resources/api_key.rb @@ -0,0 +1,46 @@ +class Avo::Resources::ApiKey < Avo::BaseResource + self.title = :name + self.includes = [] + + class ExpiredFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter ExpiredFilter, arguments: { default: { expired: false, unexpired: true } } + end + + def fields + main_panel do + field :id, as: :id, hide_on: :index + + field :name, as: :text, link_to_resource: true + field :hashed_key, as: :text, visible: -> { false } + field :user, as: :belongs_to, visible: -> { false } + field :owner, as: :belongs_to, + polymorphic_as: :owner, + types: [::User, ::OIDC::TrustedPublisher::GitHubAction] + field :last_accessed_at, as: :date_time + field :soft_deleted_at, as: :date_time + field :soft_deleted_rubygem_name, as: :text + field :expires_at, as: :date_time + + field :enabled_scopes, as: :tags + + sidebar do + field :permissions, as: :heading + + field :index_rubygems, as: :boolean + field :push_rubygem, as: :boolean + field :yank_rubygem, as: :boolean + field :add_owner, as: :boolean + field :remove_owner, as: :boolean + field :access_webhooks, as: :boolean + field :show_dashboard, as: :boolean + field :mfa, as: :boolean + end + end + + field :api_key_rubygem_scope, as: :has_one + field :ownership, as: :has_one + field :oidc_id_token, as: :has_one + end +end diff --git a/app/avo/resources/api_key_resource.rb b/app/avo/resources/api_key_resource.rb deleted file mode 100644 index dfcec27ceb2..00000000000 --- a/app/avo/resources/api_key_resource.rb +++ /dev/null @@ -1,39 +0,0 @@ -class ApiKeyResource < Avo::BaseResource - self.title = :name - self.includes = [] - - class ExpiredFilter < ScopeBooleanFilter; end - filter ExpiredFilter, arguments: { default: { expired: false, unexpired: true } } - - field :id, as: :id, hide_on: :index - - field :name, as: :text, link_to_resource: true - field :hashed_key, as: :text, visible: ->(_) { false } - field :user, as: :belongs_to, visible: ->(_) { false } - field :owner, as: :belongs_to, - polymorphic_as: :owner, - types: ["User", "OIDC::TrustedPublisher::GitHubAction"] - field :last_accessed_at, as: :date_time - field :soft_deleted_at, as: :date_time - field :soft_deleted_rubygem_name, as: :text - field :expires_at, as: :date_time - - field :scopes, as: :tags - - sidebar do - heading "Permissions" - - field :index_rubygems, as: :boolean - field :push_rubygem, as: :boolean - field :yank_rubygem, as: :boolean - field :add_owner, as: :boolean - field :remove_owner, as: :boolean - field :access_webhooks, as: :boolean - field :show_dashboard, as: :boolean - field :mfa, as: :boolean - end - - field :api_key_rubygem_scope, as: :has_one - field :ownership, as: :has_one - field :oidc_id_token, as: :has_one -end diff --git a/app/avo/resources/api_key_rubygem_scope.rb b/app/avo/resources/api_key_rubygem_scope.rb new file mode 100644 index 00000000000..e8105285828 --- /dev/null +++ b/app/avo/resources/api_key_rubygem_scope.rb @@ -0,0 +1,11 @@ +class Avo::Resources::ApiKeyRubygemScope < Avo::BaseResource + self.title = :cache_key + self.includes = [] + + def fields + field :id, as: :id + + field :api_key, as: :belongs_to + field :ownership, as: :belongs_to + end +end diff --git a/app/avo/resources/api_key_rubygem_scope_resource.rb b/app/avo/resources/api_key_rubygem_scope_resource.rb deleted file mode 100644 index 9560edba16c..00000000000 --- a/app/avo/resources/api_key_rubygem_scope_resource.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ApiKeyRubygemScopeResource < Avo::BaseResource - self.title = :cache_key - self.includes = [] - - field :id, as: :id - - field :api_key, as: :belongs_to - field :ownership, as: :belongs_to -end diff --git a/app/avo/resources/audit.rb b/app/avo/resources/audit.rb new file mode 100644 index 00000000000..f674b6b7785 --- /dev/null +++ b/app/avo/resources/audit.rb @@ -0,0 +1,40 @@ +class Avo::Resources::Audit < Avo::BaseResource + self.title = :id + self.includes = %i[ + admin_github_user + auditable + ] + + def fields + field :action, as: :text + + panel do + sidebar do + field :admin_github_user, as: :belongs_to + field :created_at, as: :date_time + field :comment, as: :text + + field :auditable, as: :belongs_to, + polymorphic_as: :auditable, + types: [::User, ::WebHook], + name: "Edited Record" + + field :action_details, as: :heading + + field :audited_changes_arguments, as: :json_viewer, only_on: :show do |_model| + record.audited_changes["arguments"] + end + field :audited_changes_fields, as: :json_viewer, only_on: :show do |_model| + record.audited_changes["fields"] + end + field :audited_changes_models, as: :text, as_html: true, only_on: :show do + record.audited_changes["models"] + end + + field :id, as: :id + end + end + + field :audited_changes, as: :audited_changes, except_on: :index + end +end diff --git a/app/avo/resources/audit_resource.rb b/app/avo/resources/audit_resource.rb deleted file mode 100644 index 548729de209..00000000000 --- a/app/avo/resources/audit_resource.rb +++ /dev/null @@ -1,36 +0,0 @@ -class AuditResource < Avo::BaseResource - self.title = :id - self.includes = %i[ - admin_github_user - auditable - ] - - field :action, as: :text - - sidebar do - field :admin_github_user, as: :belongs_to - field :created_at, as: :date_time - field :comment, as: :text - - field :auditable, as: :belongs_to, - polymorphic_as: :auditable, - types: %w[User WebHook], - name: "Edited Record" - - heading "Action Details" - - field :audited_changes_arguments, as: :json_viewer, only_on: :show do |model| - model.audited_changes["arguments"] - end - field :audited_changes_fields, as: :json_viewer, only_on: :show do |model| - model.audited_changes["fields"] - end - field :audited_changes_models, as: :text, as_html: true, only_on: :show do - model.audited_changes["models"] - end - - field :id, as: :id - end - - field :audited_changes, as: :audited_changes, except_on: :index -end diff --git a/app/avo/resources/concerns/avo_auditable_resource.rb b/app/avo/resources/concerns/avo_auditable_resource.rb index 5eb219fb67b..2c4ae137983 100644 --- a/app/avo/resources/concerns/avo_auditable_resource.rb +++ b/app/avo/resources/concerns/avo_auditable_resource.rb @@ -1,20 +1,24 @@ -module Concerns::AvoAuditableResource +module Avo::Resources::Concerns::AvoAuditableResource extend ActiveSupport::Concern class_methods do - def inherited(base) - super - base.items_holder = Avo::ItemsHolder.new - base.items_holder.instance_variable_get(:@items).replace items_holder.instance_variable_get(:@items).deep_dup - base.items_holder.invalid_fields.replace items_holder.invalid_fields.deep_dup + if false + def inherited(base) + super + base.items_holder = Avo::Resources::Items::Holder.new + base.items_holder.instance_variable_get(:@items).replace items_holder.instance_variable_get(:@items).deep_dup + base.items_holder.invalid_fields.replace items_holder.invalid_fields.deep_dup + end end end included do - panel "Auditable" do - field :comment, as: :textarea, required: true, - help: "A comment explaining why this action was taken.
Will be saved in the audit log.
Must be more than 10 characters.", - only_on: %i[new edit] + if false + panel "Auditable" do + field :comment, as: :textarea, required: true, + help: "A comment explaining why this action was taken.
Will be saved in the audit log.
Must be more than 10 characters.", + only_on: %i[new edit] + end end end end diff --git a/app/avo/resources/deletion.rb b/app/avo/resources/deletion.rb new file mode 100644 index 00000000000..a52385d8afa --- /dev/null +++ b/app/avo/resources/deletion.rb @@ -0,0 +1,15 @@ +class Avo::Resources::Deletion < Avo::BaseResource + self.title = :id + self.includes = [:version] + + def fields + field :id, as: :id + + field :created_at, as: :date_time, sortable: true, title: "Deleted At" + field :rubygem, as: :text + field :number, as: :text + field :platform, as: :text + field :user, as: :belongs_to + field :version, as: :belongs_to + end +end diff --git a/app/avo/resources/deletion_resource.rb b/app/avo/resources/deletion_resource.rb deleted file mode 100644 index fdf0cca5387..00000000000 --- a/app/avo/resources/deletion_resource.rb +++ /dev/null @@ -1,17 +0,0 @@ -class DeletionResource < Avo::BaseResource - self.title = :id - self.includes = [:version] - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - field :id, as: :id - # Fields generated from the model - field :created_at, as: :date_time, sortable: true, title: "Deleted At" - field :rubygem, as: :text - field :number, as: :text - field :platform, as: :text - field :user, as: :belongs_to - field :version, as: :belongs_to - # add fields here -end diff --git a/app/avo/resources/dependency.rb b/app/avo/resources/dependency.rb new file mode 100644 index 00000000000..1e7d213ed68 --- /dev/null +++ b/app/avo/resources/dependency.rb @@ -0,0 +1,18 @@ +class Avo::Resources::Dependency < Avo::BaseResource + self.title = :id + self.includes = [] + + def fields + field :id, as: :id, link_to_resource: true + + field :version, as: :belongs_to + field :rubygem, as: :belongs_to + field :requirements, as: :text + field :unresolved_name, as: :text + + field :scope, as: :badge, + options: { + warning: "development" + } + end +end diff --git a/app/avo/resources/dependency_resource.rb b/app/avo/resources/dependency_resource.rb deleted file mode 100644 index a3751556d8f..00000000000 --- a/app/avo/resources/dependency_resource.rb +++ /dev/null @@ -1,19 +0,0 @@ -class DependencyResource < Avo::BaseResource - self.title = :id - self.includes = [] - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - field :id, as: :id, link_to_resource: true - - field :version, as: :belongs_to - field :rubygem, as: :belongs_to - field :requirements, as: :text - field :unresolved_name, as: :text - - field :scope, as: :badge, - options: { - warning: "development" - } -end diff --git a/app/avo/resources/events_rubygem_event.rb b/app/avo/resources/events_rubygem_event.rb new file mode 100644 index 00000000000..f8a469ff8db --- /dev/null +++ b/app/avo/resources/events_rubygem_event.rb @@ -0,0 +1,30 @@ +class Avo::Resources::EventsRubygemEvent < Avo::BaseResource + self.title = :cache_key + self.includes = %i[rubygem ip_address geoip_info] + self.model_class = ::Events::RubygemEvent + + def fields + field :id, as: :id, hide_on: :index + field :created_at, as: :date_time + + field :trace_id, as: :text, format_using: proc { + if value.present? + link_to( + view == :index ? "🔗" : value, + "https://app.datadoghq.com/logs?query=#{{ + :@traceid => value, + from_ts: (record.created_at - 12.hours).to_i * 1000, + to_ts: (record.created_at + 12.hours).to_i * 1000 + }.to_query}", + { target: :_blank, rel: :noopener } + ) + end + } + + field :tag, as: :text + field :rubygem, as: :belongs_to + field :ip_address, as: :belongs_to + field :geoip_info, as: :belongs_to + field :additional, as: :event_additional, show_on: :index + end +end diff --git a/app/avo/resources/events_rubygem_event_resource.rb b/app/avo/resources/events_rubygem_event_resource.rb deleted file mode 100644 index 00e1c212574..00000000000 --- a/app/avo/resources/events_rubygem_event_resource.rb +++ /dev/null @@ -1,28 +0,0 @@ -class EventsRubygemEventResource < Avo::BaseResource - self.title = :cache_key - self.includes = %i[rubygem ip_address geoip_info] - self.model_class = ::Events::RubygemEvent - - field :id, as: :id, hide_on: :index - field :created_at, as: :date_time - - field :trace_id, as: :text, format_using: proc { - if value.present? - link_to( - view == :index ? "🔗" : value, - "https://app.datadoghq.com/logs?query=#{{ - :@traceid => value, - from_ts: (model.created_at - 12.hours).to_i * 1000, - to_ts: (model.created_at + 12.hours).to_i * 1000 - }.to_query}", - { target: :_blank, rel: :noopener } - ) - end - } - - field :tag, as: :text - field :rubygem, as: :belongs_to - field :ip_address, as: :belongs_to - field :geoip_info, as: :belongs_to - field :additional, as: :event_additional, show_on: :index -end diff --git a/app/avo/resources/events_user_event.rb b/app/avo/resources/events_user_event.rb new file mode 100644 index 00000000000..02b4c200dfa --- /dev/null +++ b/app/avo/resources/events_user_event.rb @@ -0,0 +1,30 @@ +class Avo::Resources::EventsUserEvent < Avo::BaseResource + self.title = :cache_key + self.includes = %i[user ip_address geoip_info] + self.model_class = ::Events::UserEvent + + def fields + field :id, as: :id, hide_on: :index + + field :created_at, as: :date_time + field :trace_id, as: :text, format_using: proc { + if value.present? + link_to( + view == :index ? "🔗" : value, + "https://app.datadoghq.com/logs?query=#{{ + :@traceid => value, + from_ts: (record.created_at - 12.hours).to_i * 1000, + to_ts: (record.created_at + 12.hours).to_i * 1000 + }.to_query}", + { target: :_blank, rel: :noopener } + ) + end + } + + field :tag, as: :text + field :user, as: :belongs_to + field :ip_address, as: :belongs_to + field :geoip_info, as: :belongs_to + field :additional, as: :event_additional, show_on: :index + end +end diff --git a/app/avo/resources/events_user_event_resource.rb b/app/avo/resources/events_user_event_resource.rb deleted file mode 100644 index f1293d3fb1f..00000000000 --- a/app/avo/resources/events_user_event_resource.rb +++ /dev/null @@ -1,28 +0,0 @@ -class EventsUserEventResource < Avo::BaseResource - self.title = :cache_key - self.includes = %i[user ip_address geoip_info] - self.model_class = ::Events::UserEvent - - field :id, as: :id, hide_on: :index - - field :created_at, as: :date_time - field :trace_id, as: :text, format_using: proc { - if value.present? - link_to( - view == :index ? "🔗" : value, - "https://app.datadoghq.com/logs?query=#{{ - :@traceid => value, - from_ts: (model.created_at - 12.hours).to_i * 1000, - to_ts: (model.created_at + 12.hours).to_i * 1000 - }.to_query}", - { target: :_blank, rel: :noopener } - ) - end - } - - field :tag, as: :text - field :user, as: :belongs_to - field :ip_address, as: :belongs_to - field :geoip_info, as: :belongs_to - field :additional, as: :event_additional, show_on: :index -end diff --git a/app/avo/resources/gem_download.rb b/app/avo/resources/gem_download.rb new file mode 100644 index 00000000000..40c23591359 --- /dev/null +++ b/app/avo/resources/gem_download.rb @@ -0,0 +1,32 @@ +class Avo::Resources::GemDownload < Avo::BaseResource + self.title = :inspect + self.includes = %i[rubygem version] + + self.index_query = lambda { + query.order(count: :desc) + } + + class SpecificityFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter SpecificityFilter, arguments: { default: { for_versions: true, for_rubygems: true, total: true } } + end + + def fields + field :title, as: :text, link_to_resource: true do |_model, _resource, _view| + if record.version + "#{record.version.full_name} (#{record.count.to_fs(:delimited)})" + elsif record.rubygem + "#{record.rubygem} (#{record.count.to_fs(:delimited)})" + else + "All Gems (#{record.count.to_fs(:delimited)})" + end + end + + field :rubygem, as: :belongs_to + field :version, as: :belongs_to + field :count, as: :number, sortable: true, index_text_align: :right, format_using: -> { value.to_fs(:delimited) }, default: 0 + + field :id, as: :id, hide_on: :index + end +end diff --git a/app/avo/resources/gem_download_resource.rb b/app/avo/resources/gem_download_resource.rb deleted file mode 100644 index 4cc08993f07..00000000000 --- a/app/avo/resources/gem_download_resource.rb +++ /dev/null @@ -1,27 +0,0 @@ -class GemDownloadResource < Avo::BaseResource - self.title = :inspect - self.includes = %i[rubygem version] - - self.resolve_query_scope = lambda { |model_class:| - model_class.order(count: :desc) - } - - class SpecificityFilter < ScopeBooleanFilter; end - filter SpecificityFilter, arguments: { default: { for_versions: true, for_rubygems: true, total: true } } - - field :title, as: :text, link_to_resource: true do |model, _resource, _view| - if model.version - "#{model.version.full_name} (#{model.count.to_fs(:delimited)})" - elsif model.rubygem - "#{model.rubygem} (#{model.count.to_fs(:delimited)})" - else - "All Gems (#{model.count.to_fs(:delimited)})" - end - end - - field :rubygem, as: :belongs_to - field :version, as: :belongs_to - field :count, as: :number, sortable: true, index_text_align: :right, format_using: -> { value.to_fs(:delimited) }, default: 0 - - field :id, as: :id, hide_on: :index -end diff --git a/app/avo/resources/gem_name_reservation.rb b/app/avo/resources/gem_name_reservation.rb new file mode 100644 index 00000000000..647946b7d20 --- /dev/null +++ b/app/avo/resources/gem_name_reservation.rb @@ -0,0 +1,14 @@ +class Avo::Resources::GemNameReservation < Avo::BaseResource + self.title = :name + self.includes = [] + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("name LIKE ?", "%#{params[:q]}%") + } + end + + def fields + field :id, as: :id + field :name, as: :text + end +end diff --git a/app/avo/resources/gem_name_reservation_resource.rb b/app/avo/resources/gem_name_reservation_resource.rb deleted file mode 100644 index 0b44fa49e59..00000000000 --- a/app/avo/resources/gem_name_reservation_resource.rb +++ /dev/null @@ -1,10 +0,0 @@ -class GemNameReservationResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.search_query = lambda { - scope.where("name LIKE ?", "%#{params[:q]}%") - } - - field :id, as: :id - field :name, as: :text -end diff --git a/app/avo/resources/gem_typo_exception.rb b/app/avo/resources/gem_typo_exception.rb new file mode 100644 index 00000000000..2866bfa15eb --- /dev/null +++ b/app/avo/resources/gem_typo_exception.rb @@ -0,0 +1,19 @@ +class Avo::Resources::GemTypoException < Avo::BaseResource + self.title = :name + self.includes = [] + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("name ILIKE ?", "%#{params[:q]}%") + } + end + + def fields + field :id, as: :id, hide_on: :index + + field :name, as: :text, link_to_resource: true + field :info, as: :textarea + + field :created_at, as: :date_time, sortable: true, readonly: true, only_on: %i[index show] + field :updated_at, as: :date_time, sortable: true, readonly: true, only_on: %i[index show] + end +end diff --git a/app/avo/resources/gem_typo_exception_resource.rb b/app/avo/resources/gem_typo_exception_resource.rb deleted file mode 100644 index 8512e03d2f3..00000000000 --- a/app/avo/resources/gem_typo_exception_resource.rb +++ /dev/null @@ -1,15 +0,0 @@ -class GemTypoExceptionResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.search_query = lambda { - scope.where("name ILIKE ?", "%#{params[:q]}%") - } - - field :id, as: :id, hide_on: :index - # Fields generated from the model - field :name, as: :text, link_to_resource: true - field :info, as: :textarea - # add fields here - field :created_at, as: :date_time, sortable: true, readonly: true, only_on: %i[index show] - field :updated_at, as: :date_time, sortable: true, readonly: true, only_on: %i[index show] -end diff --git a/app/avo/resources/geoip_info.rb b/app/avo/resources/geoip_info.rb new file mode 100644 index 00000000000..a72100dce0a --- /dev/null +++ b/app/avo/resources/geoip_info.rb @@ -0,0 +1,15 @@ +class Avo::Resources::GeoipInfo < Avo::BaseResource + self.title = :id + self.includes = [] + + def fields + field :continent_code, as: :text + field :country_code, as: :text + field :country_code3, as: :text + field :country_name, as: :text + field :region, as: :text + field :city, as: :text + + field :ip_addresses, as: :has_many + end +end diff --git a/app/avo/resources/geoip_info_resource.rb b/app/avo/resources/geoip_info_resource.rb deleted file mode 100644 index b049c7b965c..00000000000 --- a/app/avo/resources/geoip_info_resource.rb +++ /dev/null @@ -1,13 +0,0 @@ -class GeoipInfoResource < Avo::BaseResource - self.title = :id - self.includes = [] - - field :continent_code, as: :text - field :country_code, as: :text - field :country_code3, as: :text - field :country_name, as: :text - field :region, as: :text - field :city, as: :text - - field :ip_addresses, as: :has_many -end diff --git a/app/avo/resources/ip_address.rb b/app/avo/resources/ip_address.rb new file mode 100644 index 00000000000..084950703e6 --- /dev/null +++ b/app/avo/resources/ip_address.rb @@ -0,0 +1,22 @@ +class Avo::Resources::IpAddress < Avo::BaseResource + self.title = :ip_address + self.includes = [] + + search[:hide_on_global] = true + search[:query] = lambda { + query.where("ip_address <<= inet ?", params[:q]) + } + + def fields + field :id, as: :id + + field :ip_address, as: :text + field :hashed_ip_address, as: :textarea + field :geoip_info, as: :json_viewer + + tabs style: :pills do + field :user_events, as: :has_many + field :rubygem_events, as: :has_many + end + end +end diff --git a/app/avo/resources/ip_address_resource.rb b/app/avo/resources/ip_address_resource.rb deleted file mode 100644 index a6c99cc7271..00000000000 --- a/app/avo/resources/ip_address_resource.rb +++ /dev/null @@ -1,20 +0,0 @@ -class IpAddressResource < Avo::BaseResource - self.title = :ip_address - self.includes = [] - - self.hide_from_global_search = true - self.search_query = lambda { - scope.where("ip_address <<= inet ?", params[:q]) - } - - field :id, as: :id - - field :ip_address, as: :text - field :hashed_ip_address, as: :textarea - field :geoip_info, as: :json_viewer - - tabs style: :pills do - field :user_events, as: :has_many - field :rubygem_events, as: :has_many - end -end diff --git a/app/avo/resources/link_verification.rb b/app/avo/resources/link_verification.rb new file mode 100644 index 00000000000..90bf8b12481 --- /dev/null +++ b/app/avo/resources/link_verification.rb @@ -0,0 +1,17 @@ +class Avo::Resources::LinkVerification < Avo::BaseResource + self.title = :id + self.includes = [] + + def fields + field :id, as: :id + + field :linkable, as: :belongs_to, + polymorphic_as: :linkable, + types: [::Rubygem] + field :uri, as: :text + field :verified?, as: :boolean + field :last_verified_at, as: :date_time + field :last_failure_at, as: :date_time + field :failures_since_last_verification, as: :number + end +end diff --git a/app/avo/resources/link_verification_resource.rb b/app/avo/resources/link_verification_resource.rb deleted file mode 100644 index ee60c06d904..00000000000 --- a/app/avo/resources/link_verification_resource.rb +++ /dev/null @@ -1,19 +0,0 @@ -class LinkVerificationResource < Avo::BaseResource - self.title = :id - self.includes = [] - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - field :id, as: :id - # Fields generated from the model - field :linkable, as: :belongs_to, - polymorphic_as: :linkable, - types: %w[Rubygem] - field :uri, as: :text - field :verified?, as: :boolean - field :last_verified_at, as: :date_time - field :last_failure_at, as: :date_time - field :failures_since_last_verification, as: :number - # add fields here -end diff --git a/app/avo/resources/linkset.rb b/app/avo/resources/linkset.rb new file mode 100644 index 00000000000..7498288e8f9 --- /dev/null +++ b/app/avo/resources/linkset.rb @@ -0,0 +1,14 @@ +class Avo::Resources::Linkset < Avo::BaseResource + self.title = :id + self.includes = [:rubygem] + self.visible_on_sidebar = false + + def fields + field :id, as: :id, link_to_resource: true + field :rubygem, as: :belongs_to + + Linkset::LINKS.each do |link| + field link, as: :text, format_using: -> { link_to value, value if value.present? } + end + end +end diff --git a/app/avo/resources/linkset_resource.rb b/app/avo/resources/linkset_resource.rb deleted file mode 100644 index ac5966a45bf..00000000000 --- a/app/avo/resources/linkset_resource.rb +++ /dev/null @@ -1,12 +0,0 @@ -class LinksetResource < Avo::BaseResource - self.title = :id - self.includes = [:rubygem] - self.visible_on_sidebar = false - - field :id, as: :id, link_to_resource: true - field :rubygem, as: :belongs_to - - Linkset::LINKS.each do |link| - field link, as: :text, format_using: -> { link_to value, value if value.present? } - end -end diff --git a/app/avo/resources/log_ticket.rb b/app/avo/resources/log_ticket.rb new file mode 100644 index 00000000000..893f8382a2b --- /dev/null +++ b/app/avo/resources/log_ticket.rb @@ -0,0 +1,22 @@ +class Avo::Resources::LogTicket < Avo::BaseResource + self.title = :id + self.includes = [] + + class BackendFilter < Avo::Filters::ScopeBooleanFilter; end + class StatusFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter BackendFilter, arguments: { default: LogTicket.backends.transform_values { true } } + filter StatusFilter, arguments: { default: LogTicket.statuses.transform_values { true } } + end + + def fields + field :id, as: :id, link_to_resource: true + + field :key, as: :text + field :directory, as: :text + field :backend, as: :select, enum: LogTicket.backends + field :status, as: :select, enum: LogTicket.statuses + field :processed_count, as: :number, sortable: true + end +end diff --git a/app/avo/resources/log_ticket_resource.rb b/app/avo/resources/log_ticket_resource.rb deleted file mode 100644 index 1a6c88419e2..00000000000 --- a/app/avo/resources/log_ticket_resource.rb +++ /dev/null @@ -1,18 +0,0 @@ -class LogTicketResource < Avo::BaseResource - self.title = :id - self.includes = [] - - class BackendFilter < ScopeBooleanFilter; end - filter BackendFilter, arguments: { default: LogTicket.backends.transform_values { true } } - - class StatusFilter < ScopeBooleanFilter; end - filter StatusFilter, arguments: { default: LogTicket.statuses.transform_values { true } } - - field :id, as: :id, link_to_resource: true - - field :key, as: :text - field :directory, as: :text - field :backend, as: :select, enum: LogTicket.backends - field :status, as: :select, enum: LogTicket.statuses - field :processed_count, as: :number, sortable: true -end diff --git a/app/avo/resources/maintenance_tasks_run.rb b/app/avo/resources/maintenance_tasks_run.rb new file mode 100644 index 00000000000..623519b2de5 --- /dev/null +++ b/app/avo/resources/maintenance_tasks_run.rb @@ -0,0 +1,30 @@ +class Avo::Resources::MaintenanceTasksRun < Avo::BaseResource + self.title = :id + self.includes = [] + self.model_class = ::MaintenanceTasks::Run + + class StatusFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter StatusFilter, arguments: { default: MaintenanceTasks::Run.statuses.transform_values { true } } + end + + def fields + field :id, as: :id + + field :task_name, as: :text + field :started_at, as: :date_time, sortable: true + field :ended_at, as: :date_time, sortable: true + field :time_running, as: :number, sortable: true + field :tick_count, as: :number + field :tick_total, as: :number + field :job_id, as: :text + field :cursor, as: :number + field :status, as: :select, enum: MaintenanceTasks::Run.statuses + field :error_class, as: :text + field :error_message, as: :text + field :backtrace, as: :textarea + field :arguments, as: :textarea + field :lock_version, as: :number + end +end diff --git a/app/avo/resources/maintenance_tasks_run_resource.rb b/app/avo/resources/maintenance_tasks_run_resource.rb deleted file mode 100644 index 0f553fdb3a5..00000000000 --- a/app/avo/resources/maintenance_tasks_run_resource.rb +++ /dev/null @@ -1,29 +0,0 @@ -class MaintenanceTasksRunResource < Avo::BaseResource - self.title = :id - self.includes = [] - self.model_class = ::MaintenanceTasks::Run - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - class StatusFilter < ScopeBooleanFilter; end - filter StatusFilter, arguments: { default: MaintenanceTasks::Run.statuses.transform_values { true } } - - field :id, as: :id - # Fields generated from the model - field :task_name, as: :text - field :started_at, as: :date_time, sortable: true - field :ended_at, as: :date_time, sortable: true - field :time_running, as: :number, sortable: true - field :tick_count, as: :number - field :tick_total, as: :number - field :job_id, as: :text - field :cursor, as: :number - field :status, as: :select, enum: MaintenanceTasks::Run.statuses - field :error_class, as: :text - field :error_message, as: :text - field :backtrace, as: :textarea - field :arguments, as: :textarea - field :lock_version, as: :number - # add fields here -end diff --git a/app/avo/resources/membership.rb b/app/avo/resources/membership.rb new file mode 100644 index 00000000000..40b361d034d --- /dev/null +++ b/app/avo/resources/membership.rb @@ -0,0 +1,16 @@ +class Avo::Resources::Membership < Avo::BaseResource + self.title = :id + self.includes = [] + + class ConfirmedFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter ConfirmedFilter, arguments: { default: { confirmed: true, unconfirmed: false } } + end + + def fields + field :id, as: :id + field :user, as: :belongs_to + field :organization, as: :belongs_to + end +end diff --git a/app/avo/resources/membership_resource.rb b/app/avo/resources/membership_resource.rb deleted file mode 100644 index 34ade886951..00000000000 --- a/app/avo/resources/membership_resource.rb +++ /dev/null @@ -1,11 +0,0 @@ -class MembershipResource < Avo::BaseResource - self.title = :id - self.includes = [] - - class ConfirmedFilter < ScopeBooleanFilter; end - filter ConfirmedFilter, arguments: { default: { confirmed: true, unconfirmed: false } } - - field :id, as: :id - field :user, as: :belongs_to - field :organization, as: :belongs_to -end diff --git a/app/avo/resources/oidc_api_key_role.rb b/app/avo/resources/oidc_api_key_role.rb new file mode 100644 index 00000000000..8dc81b51b6a --- /dev/null +++ b/app/avo/resources/oidc_api_key_role.rb @@ -0,0 +1,34 @@ +class Avo::Resources::OIDCApiKeyRole < Avo::BaseResource + self.title = :token + self.includes = [] + self.model_class = ::OIDC::ApiKeyRole + + def fields + field :token, as: :text, link_to_resource: true, readonly: true + field :id, as: :id, link_to_resource: true, hide_on: :index + # Fields generated from the model + field :name, as: :text + field :provider, as: :belongs_to + field :user, as: :belongs_to, searchable: true + field :api_key_permissions, as: :nested do + field :valid_for, as: :text, format_using: -> { value&.iso8601 } + field :scopes, as: :tags, suggestions: ApiKey::API_SCOPES.map { { label: _1, value: _1 } }, enforce_suggestions: true + field :gems, as: :tags, suggestions: -> { Rubygem.limit(10).pluck(:name).map { { value: _1, label: _1 } } } + end + field :access_policy, as: :nested do + field :statements, as: :array_of, field: :nested do + field :effect, as: :select, options: { "Allow" => "allow" }, default: "Allow" + field :principal, as: :nested, field_options: { stacked: false } do + field :oidc, as: :text + end + field :conditions, as: :array_of, field: :nested, field_options: { stacked: false } do + field :operator, as: :select, options: OIDC::AccessPolicy::Statement::Condition::OPERATORS.index_by(&:titleize) + field :claim, as: :text + field :value, as: :text + end + end + end + + field :id_tokens, as: :has_many + end +end diff --git a/app/avo/resources/oidc_api_key_role_resource.rb b/app/avo/resources/oidc_api_key_role_resource.rb deleted file mode 100644 index 3f59087e912..00000000000 --- a/app/avo/resources/oidc_api_key_role_resource.rb +++ /dev/null @@ -1,36 +0,0 @@ -class OIDCApiKeyRoleResource < Avo::BaseResource - self.title = :token - self.includes = [] - self.model_class = ::OIDC::ApiKeyRole - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - field :token, as: :text, link_to_resource: true, readonly: true - field :id, as: :id, link_to_resource: true, hide_on: :index - # Fields generated from the model - field :name, as: :text - field :provider, as: :belongs_to - field :user, as: :belongs_to, searchable: true - field :api_key_permissions, as: :nested do - field :valid_for, as: :text, format_using: -> { value&.iso8601 } - field :scopes, as: :tags, suggestions: ApiKey::API_SCOPES.map { { label: _1, value: _1 } }, enforce_suggestions: true - field :gems, as: :tags, suggestions: -> { Rubygem.limit(10).pluck(:name).map { { value: _1, label: _1 } } } - end - field :access_policy, as: :nested do - field :statements, as: :array_of, field: :nested do - field :effect, as: :select, options: { "Allow" => "allow" }, default: "Allow" - field :principal, as: :nested, field_options: { stacked: false } do - field :oidc, as: :text - end - field :conditions, as: :array_of, field: :nested, field_options: { stacked: false } do - field :operator, as: :select, options: OIDC::AccessPolicy::Statement::Condition::OPERATORS.index_by(&:titleize) - field :claim, as: :text - field :value, as: :text - end - end - end - - field :id_tokens, as: :has_many - # add fields here -end diff --git a/app/avo/resources/oidc_id_token.rb b/app/avo/resources/oidc_id_token.rb new file mode 100644 index 00000000000..48ae92fe2c0 --- /dev/null +++ b/app/avo/resources/oidc_id_token.rb @@ -0,0 +1,21 @@ +class Avo::Resources::OIDCIdToken < Avo::BaseResource + self.title = :id + self.includes = [] + self.model_class = ::OIDC::IdToken + + def fields + field :id, as: :id + # Fields generated from the model + field :api_key_role, as: :belongs_to + field :provider, as: :has_one + field :api_key, as: :has_one + + field :jwt, as: :heading + field :claims, as: :key_value, stacked: true do + record.jwt.fetch("claims") + end + field :header, as: :key_value, stacked: true do + record.jwt.fetch("header") + end + end +end diff --git a/app/avo/resources/oidc_id_token_resource.rb b/app/avo/resources/oidc_id_token_resource.rb deleted file mode 100644 index bda90ed7025..00000000000 --- a/app/avo/resources/oidc_id_token_resource.rb +++ /dev/null @@ -1,23 +0,0 @@ -class OIDCIdTokenResource < Avo::BaseResource - self.title = :id - self.includes = [] - self.model_class = ::OIDC::IdToken - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - field :id, as: :id - # Fields generated from the model - field :api_key_role, as: :belongs_to - field :provider, as: :has_one - field :api_key, as: :has_one - - heading "JWT" - field :claims, as: :key_value, stacked: true do - model.jwt.fetch("claims") - end - field :header, as: :key_value, stacked: true do - model.jwt.fetch("header") - end - # add fields here -end diff --git a/app/avo/resources/oidc_pending_trusted_publisher.rb b/app/avo/resources/oidc_pending_trusted_publisher.rb new file mode 100644 index 00000000000..885166c0818 --- /dev/null +++ b/app/avo/resources/oidc_pending_trusted_publisher.rb @@ -0,0 +1,20 @@ +class Avo::Resources::OIDCPendingTrustedPublisher < Avo::BaseResource + self.title = :id + self.includes = [] + self.model_class = ::OIDC::PendingTrustedPublisher + + class ExpiredFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter ExpiredFilter, arguments: { default: { expired: false, unexpired: true } } + end + + def fields + field :id, as: :id + + field :rubygem_name, as: :text + field :user, as: :belongs_to + field :trusted_publisher, as: :belongs_to, polymorphic_as: :trusted_publisher + field :expires_at, as: :date_time + end +end diff --git a/app/avo/resources/oidc_pending_trusted_publisher_resource.rb b/app/avo/resources/oidc_pending_trusted_publisher_resource.rb deleted file mode 100644 index f546d3a8df1..00000000000 --- a/app/avo/resources/oidc_pending_trusted_publisher_resource.rb +++ /dev/null @@ -1,16 +0,0 @@ -class OIDCPendingTrustedPublisherResource < Avo::BaseResource - self.title = :id - self.includes = [] - self.model_class = ::OIDC::PendingTrustedPublisher - - class ExpiredFilter < ScopeBooleanFilter; end - filter ExpiredFilter, arguments: { default: { expired: false, unexpired: true } } - - field :id, as: :id - # Fields generated from the model - field :rubygem_name, as: :text - field :user, as: :belongs_to - field :trusted_publisher, as: :belongs_to, polymorphic_as: :trusted_publisher - field :expires_at, as: :date_time - # add fields here -end diff --git a/app/avo/resources/oidc_provider.rb b/app/avo/resources/oidc_provider.rb new file mode 100644 index 00000000000..74cf4d35f10 --- /dev/null +++ b/app/avo/resources/oidc_provider.rb @@ -0,0 +1,23 @@ +class Avo::Resources::OIDCProvider < Avo::BaseResource + self.title = :issuer + self.includes = [] + self.model_class = ::OIDC::Provider + + def actions + action Avo::Actions::RefreshOIDCProvider + end + + def fields + field :issuer, as: :text, link_to_resource: true + field :configuration, as: :nested do + visible_on = %i[edit new] + OIDC::Provider::Configuration.then { (_1.required_attributes + _1.optional_attributes) - fields.map(&:id) }.each do |k| + field k, as: (k.to_s.end_with?("s_supported") ? :tags : :text), visible: ->(_) { visible_on.include?(view) || value.send(k).present? } + end + end + field :jwks, as: :array_of, field: :json_viewer, hide_on: :index + field :api_key_roles, as: :has_many + + field :id, as: :id + end +end diff --git a/app/avo/resources/oidc_provider_resource.rb b/app/avo/resources/oidc_provider_resource.rb deleted file mode 100644 index 8a2fa0fe6d4..00000000000 --- a/app/avo/resources/oidc_provider_resource.rb +++ /dev/null @@ -1,20 +0,0 @@ -class OIDCProviderResource < Avo::BaseResource - self.title = :issuer - self.includes = [] - self.model_class = ::OIDC::Provider - - action RefreshOIDCProvider - - # Fields generated from the model - field :issuer, as: :text, link_to_resource: true - field :configuration, as: :nested do - visible_on = %i[edit new] - OIDC::Provider::Configuration.then { (_1.required_attributes + _1.optional_attributes) - fields.map(&:id) }.each do |k| - field k, as: (k.to_s.end_with?("s_supported") ? :tags : :text), visible: ->(_) { visible_on.include?(view) || value.send(k).present? } - end - end - field :jwks, as: :array_of, field: :json_viewer, hide_on: :index - field :api_key_roles, as: :has_many - # add fields here - field :id, as: :id -end diff --git a/app/avo/resources/oidc_rubygem_trusted_publisher.rb b/app/avo/resources/oidc_rubygem_trusted_publisher.rb new file mode 100644 index 00000000000..e7e9d13f532 --- /dev/null +++ b/app/avo/resources/oidc_rubygem_trusted_publisher.rb @@ -0,0 +1,12 @@ +class Avo::Resources::OIDCRubygemTrustedPublisher < Avo::BaseResource + self.title = :id + self.includes = [:trusted_publisher] + self.model_class = ::OIDC::RubygemTrustedPublisher + + def fields + field :id, as: :id + + field :rubygem, as: :belongs_to + field :trusted_publisher, as: :belongs_to, polymorphic_as: :trusted_publisher + end +end diff --git a/app/avo/resources/oidc_rubygem_trusted_publisher_resource.rb b/app/avo/resources/oidc_rubygem_trusted_publisher_resource.rb deleted file mode 100644 index 96c63c43096..00000000000 --- a/app/avo/resources/oidc_rubygem_trusted_publisher_resource.rb +++ /dev/null @@ -1,11 +0,0 @@ -class OIDCRubygemTrustedPublisherResource < Avo::BaseResource - self.title = :id - self.includes = [:trusted_publisher] - self.model_class = ::OIDC::RubygemTrustedPublisher - - field :id, as: :id - # Fields generated from the model - field :rubygem, as: :belongs_to - field :trusted_publisher, as: :belongs_to, polymorphic_as: :trusted_publisher - # add fields here -end diff --git a/app/avo/resources/oidc_trusted_publisher_github_action.rb b/app/avo/resources/oidc_trusted_publisher_github_action.rb new file mode 100644 index 00000000000..0a850ed2e21 --- /dev/null +++ b/app/avo/resources/oidc_trusted_publisher_github_action.rb @@ -0,0 +1,20 @@ +class Avo::Resources::OIDCTrustedPublisherGitHubAction < Avo::BaseResource + self.title = :name + self.includes = [] + self.model_class = ::OIDC::TrustedPublisher::GitHubAction + + def fields + field :id, as: :id + + field :repository_owner, as: :text + field :repository_name, as: :text + field :repository_owner_id, as: :text + field :workflow_filename, as: :text + field :environment, as: :text + + field :rubygem_trusted_publishers, as: :has_many + field :pending_trusted_publishers, as: :has_many + field :rubygems, as: :has_many, through: :rubygem_trusted_publishers + field :api_keys, as: :has_many, inverse_of: :owner + end +end diff --git a/app/avo/resources/oidc_trusted_publisher_github_action_resource.rb b/app/avo/resources/oidc_trusted_publisher_github_action_resource.rb deleted file mode 100644 index 0ea00fd83e4..00000000000 --- a/app/avo/resources/oidc_trusted_publisher_github_action_resource.rb +++ /dev/null @@ -1,19 +0,0 @@ -class OIDCTrustedPublisherGitHubActionResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.model_class = ::OIDC::TrustedPublisher::GitHubAction - - field :id, as: :id - # Fields generated from the model - field :repository_owner, as: :text - field :repository_name, as: :text - field :repository_owner_id, as: :text - field :workflow_filename, as: :text - field :environment, as: :text - # add fields here - # - field :rubygem_trusted_publishers, as: :has_many - field :pending_trusted_publishers, as: :has_many - field :rubygems, as: :has_many, through: :rubygem_trusted_publishers - field :api_keys, as: :has_many, inverse_of: :owner -end diff --git a/app/avo/resources/organization.rb b/app/avo/resources/organization.rb new file mode 100644 index 00000000000..545b67ffc0e --- /dev/null +++ b/app/avo/resources/organization.rb @@ -0,0 +1,22 @@ +class Avo::Resources::Organization < Avo::BaseResource + self.title = :name + self.includes = [] + search[:query] = lambda { + query.where("name LIKE ? OR handle LIKE ?", "%#{params[:q]}%", "%#{params[:q]}%") + } + + class DeletedFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter DeletedFilter, arguments: { default: { not_deleted: true, deleted: false } } + end + + def fields + field :id, as: :id + # Fields generated from the model + field :handle, as: :text + field :name, as: :text + field :deleted_at, as: :date_time + # add fields here + end +end diff --git a/app/avo/resources/organization_resource.rb b/app/avo/resources/organization_resource.rb deleted file mode 100644 index 592fdb766d8..00000000000 --- a/app/avo/resources/organization_resource.rb +++ /dev/null @@ -1,18 +0,0 @@ -class OrganizationResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.search_query = lambda { - scope.where("name LIKE ? OR handle LIKE ?", "%#{params[:q]}%", "%#{params[:q]}%") - } - self.unscoped_queries_on_index = true - - class DeletedFilter < ScopeBooleanFilter; end - filter DeletedFilter, arguments: { default: { not_deleted: true, deleted: false } } - - field :id, as: :id - # Fields generated from the model - field :handle, as: :text - field :name, as: :text - field :deleted_at, as: :date_time - # add fields here -end diff --git a/app/avo/resources/ownership.rb b/app/avo/resources/ownership.rb new file mode 100644 index 00000000000..3c45bf27da1 --- /dev/null +++ b/app/avo/resources/ownership.rb @@ -0,0 +1,34 @@ +class Avo::Resources::Ownership < Avo::BaseResource + self.title = :cache_key + self.includes = [] + + class ConfirmedFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter ConfirmedFilter, arguments: { default: { confirmed: true, unconfirmed: true } } + end + + def fields + field :id, as: :id, link_to_resource: true + + field :user, as: :belongs_to + field :rubygem, as: :belongs_to + + field :token, as: :heading + + field :token, as: :text, visible: -> { false } + field :token_expires_at, as: :date_time + field :api_key_rubygem_scopes, as: :has_many + + field :notifications, as: :heading + + field :push_notifier, as: :boolean + field :owner_notifier, as: :boolean + field :ownership_request_notifier, as: :boolean + + field :authorization, as: :heading + + field :authorizer, as: :belongs_to + field :confirmed_at, as: :date_time + end +end diff --git a/app/avo/resources/ownership_resource.rb b/app/avo/resources/ownership_resource.rb deleted file mode 100644 index cd51054bbd0..00000000000 --- a/app/avo/resources/ownership_resource.rb +++ /dev/null @@ -1,29 +0,0 @@ -class OwnershipResource < Avo::BaseResource - self.title = :cache_key - self.includes = [] - - class ConfirmedFilter < ScopeBooleanFilter; end - filter ConfirmedFilter, arguments: { default: { confirmed: true, unconfirmed: true } } - - field :id, as: :id, link_to_resource: true - - field :user, as: :belongs_to - field :rubygem, as: :belongs_to - - heading "Token" - - field :token, as: :text, visible: ->(_) { false } - field :token_expires_at, as: :date_time - field :api_key_rubygem_scopes, as: :has_many - - heading "Notifications" - - field :push_notifier, as: :boolean - field :owner_notifier, as: :boolean - field :ownership_request_notifier, as: :boolean - - heading "Authorization" - - field :authorizer, as: :belongs_to - field :confirmed_at, as: :date_time -end diff --git a/app/avo/resources/rubygem.rb b/app/avo/resources/rubygem.rb new file mode 100644 index 00000000000..6b9b1d58a48 --- /dev/null +++ b/app/avo/resources/rubygem.rb @@ -0,0 +1,54 @@ +class Avo::Resources::Rubygem < Avo::BaseResource + self.title = :name + self.includes = [] + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("name LIKE ?", "%#{params[:q]}%") + } + end + + def actions + action Avo::Actions::ReleaseReservedNamespace + action Avo::Actions::AddOwner + action Avo::Actions::YankRubygem + action Avo::Actions::UploadInfoFile + action Avo::Actions::UploadNamesFile + action Avo::Actions::UploadVersionsFile + end + + class IndexedFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter IndexedFilter, arguments: { default: { with_versions: true, without_versions: true } } + end + + def fields + field :name, as: :text, link_to_resource: true + field :indexed, as: :boolean + field :slug, as: :text, hide_on: :index + field :id, as: :id, hide_on: :index + field :protected_days, as: :number, hide_on: :index + + tabs style: :pills do + field :versions, as: :has_many + field :latest_version, as: :has_one + + field :ownerships, as: :has_many + field :ownerships_including_unconfirmed, as: :has_many + field :ownership_calls, as: :has_many + field :ownership_requests, as: :has_many + + field :subscriptions, as: :has_many + field :subscribers, as: :has_many, through: :subscriptions + + field :web_hooks, as: :has_many + field :linkset, as: :has_one + field :gem_download, as: :has_one + + field :link_verifications, as: :has_many + field :oidc_rubygem_trusted_publishers, as: :has_many + + field :audits, as: :has_many + end + end +end diff --git a/app/avo/resources/rubygem_resource.rb b/app/avo/resources/rubygem_resource.rb deleted file mode 100644 index 09636f782de..00000000000 --- a/app/avo/resources/rubygem_resource.rb +++ /dev/null @@ -1,47 +0,0 @@ -class RubygemResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.search_query = lambda { - scope.where("name LIKE ?", "%#{params[:q]}%") - } - - action ReleaseReservedNamespace - action AddOwner - action YankRubygem - action UploadInfoFile - action UploadNamesFile - action UploadVersionsFile - - class IndexedFilter < ScopeBooleanFilter; end - filter IndexedFilter, arguments: { default: { with_versions: true, without_versions: true } } - - # Fields generated from the model - field :name, as: :text, link_to_resource: true - field :indexed, as: :boolean - field :slug, as: :text, hide_on: :index - field :id, as: :id, hide_on: :index - field :protected_days, as: :number, hide_on: :index - - tabs style: :pills do - field :versions, as: :has_many - field :latest_version, as: :has_one - - field :ownerships, as: :has_many - field :ownerships_including_unconfirmed, as: :has_many - field :ownership_calls, as: :has_many - field :ownership_requests, as: :has_many - - field :subscriptions, as: :has_many - field :subscribers, as: :has_many, through: :subscriptions - - field :web_hooks, as: :has_many - field :linkset, as: :has_one - field :gem_download, as: :has_one - - field :link_verifications, as: :has_many - field :oidc_rubygem_trusted_publishers, as: :has_many - - field :events, as: :has_many - field :audits, as: :has_many - end -end diff --git a/app/avo/resources/sendgrid_event.rb b/app/avo/resources/sendgrid_event.rb new file mode 100644 index 00000000000..c9d57d8a636 --- /dev/null +++ b/app/avo/resources/sendgrid_event.rb @@ -0,0 +1,27 @@ +class Avo::Resources::SendgridEvent < Avo::BaseResource + self.title = :sendgrid_id + self.includes = [] + # self.search_query = -> do + # query.ransack(id_eq: params[:q], m: "or").result(distinct: false) + # end + + class StatusFilter < Avo::Filters::ScopeBooleanFilter; end + class EventTypeFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter StatusFilter, arguments: { default: SendgridEvent.statuses.transform_values { true } } + filter EventTypeFilter, arguments: { default: SendgridEvent.event_types.transform_values { true } } + filter Avo::Filters::EmailFilter + end + + def fields + field :id, as: :id, hide_on: :index + + field :sendgrid_id, as: :text, link_to_resource: true + field :email, as: :text + field :event_type, as: :text + field :occurred_at, as: :date_time, sortable: true + field :payload, as: :json_viewer + field :status, as: :select, enum: SendgridEvent.statuses + end +end diff --git a/app/avo/resources/sendgrid_event_resource.rb b/app/avo/resources/sendgrid_event_resource.rb deleted file mode 100644 index 9328ed102db..00000000000 --- a/app/avo/resources/sendgrid_event_resource.rb +++ /dev/null @@ -1,25 +0,0 @@ -class SendgridEventResource < Avo::BaseResource - self.title = :sendgrid_id - self.includes = [] - # self.search_query = -> do - # scope.ransack(id_eq: params[:q], m: "or").result(distinct: false) - # end - - class StatusFilter < ScopeBooleanFilter; end - filter StatusFilter, arguments: { default: SendgridEvent.statuses.transform_values { true } } - - class EventTypeFilter < ScopeBooleanFilter; end - filter EventTypeFilter, arguments: { default: SendgridEvent.event_types.transform_values { true } } - - filter EmailFilter - - field :id, as: :id, hide_on: :index - # Fields generated from the model - field :sendgrid_id, as: :text, link_to_resource: true - field :email, as: :text - field :event_type, as: :text - field :occurred_at, as: :date_time, sortable: true - field :payload, as: :json_viewer - field :status, as: :select, enum: SendgridEvent.statuses - # add fields here -end diff --git a/app/avo/resources/user.rb b/app/avo/resources/user.rb new file mode 100644 index 00000000000..bf812c2d23b --- /dev/null +++ b/app/avo/resources/user.rb @@ -0,0 +1,77 @@ +class Avo::Resources::User < Avo::BaseResource + self.title = :name + self.includes = [] + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("email LIKE ? OR handle LIKE ?", "%#{params[:q]}%", "%#{params[:q]}%") + } + end + + def actions + action Avo::Actions::BlockUser + action Avo::Actions::CreateUser + action Avo::Actions::ChangeUserEmail + action Avo::Actions::ResetApiKey + action Avo::Actions::ResetUser2fa + action Avo::Actions::YankRubygemsForUser + action Avo::Actions::YankUser + end + + def fields # rubocop:disable Metrics + field :id, as: :id + + field :email, as: :text + field :gravatar, + as: :gravatar, + rounded: true, + size: 48 do |_, _, _| + record.email + end + + field :email_confirmed, as: :boolean + + field :email_reset, as: :boolean + field :handle, as: :text + field :public_email, as: :boolean + field :twitter_username, as: :text, as_html: true, format_using: -> { link_to value, "https://twitter.com/#{value}", target: :_blank, rel: :noopener if value.present? } + field :unconfirmed_email, as: :text + + field :mail_fails, as: :number + field :blocked_email, as: :text + + tabs style: :pills do + tab "Auth" do + field :encrypted_password, as: :password, visible: -> { false } + field :totp_seed, as: :text, visible: -> { false } + field :mfa_seed, as: :text, visible: -> { false } # legacy field + field :mfa_level, as: :select, enum: ::User.mfa_levels + field :mfa_recovery_codes, as: :text, visible: -> { false } + field :mfa_hashed_recovery_codes, as: :text, visible: -> { false } + field :webauthn_id, as: :text + field :remember_token_expires_at, as: :date_time + field :api_key, as: :text, visible: -> { false } + field :confirmation_token, as: :text, visible: -> { false } + field :remember_token, as: :text, visible: -> { false } + field :salt, as: :text, visible: -> { false } + field :token, as: :text, visible: -> { false } + field :token_expires_at, as: :date_time + end + field :ownerships, as: :has_many + field :rubygems, as: :has_many, through: :ownerships + field :subscriptions, as: :has_many + field :subscribed_gems, as: :has_many, through: :subscriptions + field :deletions, as: :has_many + field :web_hooks, as: :has_many + field :unconfirmed_ownerships, as: :has_many + field :api_keys, as: :has_many, name: "API Keys" + field :ownership_calls, as: :has_many + field :ownership_requests, as: :has_many + field :pushed_versions, as: :has_many + field :oidc_api_key_roles, as: :has_many + field :webauthn_credentials, as: :has_many + field :webauthn_verification, as: :has_one + + field :audits, as: :has_many + end + end +end diff --git a/app/avo/resources/user_resource.rb b/app/avo/resources/user_resource.rb deleted file mode 100644 index acba5dfe213..00000000000 --- a/app/avo/resources/user_resource.rb +++ /dev/null @@ -1,80 +0,0 @@ -class UserResource < Avo::BaseResource - self.title = :name - self.includes = [] - self.search_query = lambda { - scope.where("email LIKE ? OR handle LIKE ?", "%#{params[:q]}%", "%#{params[:q]}%") - } - self.unscoped_queries_on_index = true - - class DeletedFilter < ScopeBooleanFilter; end - filter DeletedFilter, arguments: { default: { not_deleted: true, deleted: false } } - - action BlockUser - action CreateUser - action ChangeUserEmail - action ResetApiKey - action ResetUser2fa - action YankRubygemsForUser - action YankUser - - field :id, as: :id - # Fields generated from the model - field :email, as: :text - field :gravatar, - as: :gravatar, - rounded: true, - size: 48 do |_, _, _| - model.email - end - - field :email_confirmed, as: :boolean - - field :email_reset, as: :boolean - field :handle, as: :text - field :public_email, as: :boolean - field :twitter_username, as: :text, as_html: true, format_using: -> { link_to value, "https://twitter.com/#{value}", target: :_blank, rel: :noopener if value.present? } - field :unconfirmed_email, as: :text - - field :mail_fails, as: :number - field :blocked_email, as: :text - - field :deleted_at, as: :date_time - - tabs style: :pills do - tab "Auth" do - field :encrypted_password, as: :password, visible: ->(_) { false } - field :totp_seed, as: :text, visible: ->(_) { false } - field :mfa_seed, as: :text, visible: ->(_) { false } # legacy field - field :mfa_level, as: :select, enum: ::User.mfa_levels - field :mfa_recovery_codes, as: :text, visible: ->(_) { false } - field :mfa_hashed_recovery_codes, as: :text, visible: ->(_) { false } - field :webauthn_id, as: :text - field :remember_token_expires_at, as: :date_time - field :api_key, as: :text, visible: ->(_) { false } - field :confirmation_token, as: :text, visible: ->(_) { false } - field :remember_token, as: :text, visible: ->(_) { false } - field :salt, as: :text, visible: ->(_) { false } - field :token, as: :text, visible: ->(_) { false } - field :token_expires_at, as: :date_time - end - field :ownerships, as: :has_many - field :rubygems, as: :has_many, through: :ownerships - field :memberships, as: :has_many - field :organizations, as: :has_many, through: :memberships - field :subscriptions, as: :has_many - field :subscribed_gems, as: :has_many, through: :subscriptions - field :deletions, as: :has_many - field :web_hooks, as: :has_many - field :unconfirmed_ownerships, as: :has_many - field :api_keys, as: :has_many, name: "API Keys" - field :ownership_calls, as: :has_many - field :ownership_requests, as: :has_many - field :pushed_versions, as: :has_many - field :oidc_api_key_roles, as: :has_many - field :webauthn_credentials, as: :has_many - field :webauthn_verification, as: :has_one - - field :audits, as: :has_many - field :events, as: :has_many - end -end diff --git a/app/avo/resources/version.rb b/app/avo/resources/version.rb new file mode 100644 index 00000000000..cd67a2803af --- /dev/null +++ b/app/avo/resources/version.rb @@ -0,0 +1,78 @@ +class Avo::Resources::Version < Avo::BaseResource + self.title = :full_name + self.includes = [:rubygem] + if Gem.loaded_specs["avo-pro"] + search[:query] = lambda { + query.where("full_name LIKE ?", "#{params[:q]}%") + } + end + + def actions + action Avo::Actions::RestoreVersion + end + + class IndexedFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter IndexedFilter, arguments: { default: { indexed: true, yanked: true } } + end + + def fields # rubocop:disable Metrics + field :full_name, as: :text, link_to_resource: true + field :id, as: :id, hide_on: :index, as_html: true do |_id, *_args| + link_to record.id, main_app.rubygem_version_url(record.rubygem.slug, record.slug) + end + + field :rubygem, as: :belongs_to + field :slug, as: :text, hide_on: :index + field :number, as: :text + field :platform, as: :text + + field :canonical_number, as: :text + + field :indexed, as: :boolean + field :prerelease, as: :boolean + field :position, as: :number + field :latest, as: :boolean + + field :yanked_at, as: :date_time, sortable: true + + field :pusher, as: :belongs_to, class: "User" + field :pusher_api_key, as: :belongs_to, class: "ApiKey" + + tabs do + tab "Metadata", description: "Metadata that comes from the gemspec" do + panel do + field :summary, as: :textarea + field :description, as: :textarea + field :authors, as: :textarea + field :licenses, as: :textarea + field :cert_chain, as: :textarea + field :built_at, as: :date_time, sortable: true + field :metadata, as: :key_value, stacked: true + end + end + + tab "Runtime information" do + panel do + field :size, as: :number, sortable: true + field :requirements, as: :textarea + field :required_ruby_version, as: :text + field :sha256, as: :text + field :required_rubygems_version, as: :text + end + end + + tab "API" do + panel do + field :info_checksum, as: :text + field :yanked_info_checksum, as: :text + end + end + + field :dependencies, as: :has_many + field :gem_download, as: :has_one, name: "Downloads" + field :deletion, as: :has_one + end + end +end diff --git a/app/avo/resources/version_resource.rb b/app/avo/resources/version_resource.rb deleted file mode 100644 index 62d853fb69c..00000000000 --- a/app/avo/resources/version_resource.rb +++ /dev/null @@ -1,70 +0,0 @@ -class VersionResource < Avo::BaseResource - self.title = :full_name - self.includes = [:rubygem] - self.search_query = lambda { - scope.where("full_name LIKE ?", "#{params[:q]}%") - } - - action RestoreVersion - action VersionAfterWrite - - class IndexedFilter < ScopeBooleanFilter; end - filter IndexedFilter, arguments: { default: { indexed: true, yanked: true } } - - field :full_name, as: :text, link_to_resource: true - field :id, as: :id, hide_on: :index, as_html: true do |_id, *_args| - link_to model.id, main_app.rubygem_version_url(model.rubygem.slug, model.slug) - end - - field :rubygem, as: :belongs_to - field :slug, as: :text, hide_on: :index - field :number, as: :text - field :platform, as: :text - - field :canonical_number, as: :text - - field :indexed, as: :boolean - field :prerelease, as: :boolean - field :position, as: :number - field :latest, as: :boolean - - field :yanked_at, as: :date_time, sortable: true - - field :pusher, as: :belongs_to, class: "User" - field :pusher_api_key, as: :belongs_to, class: "ApiKey" - - tabs do - tab "Metadata", description: "Metadata that comes from the gemspec" do - panel do - field :summary, as: :textarea - field :description, as: :textarea - field :authors, as: :textarea - field :licenses, as: :textarea - field :cert_chain, as: :textarea - field :built_at, as: :date_time, sortable: true - field :metadata, as: :key_value, stacked: true - end - end - - tab "Runtime information" do - panel do - field :size, as: :number, sortable: true - field :requirements, as: :textarea - field :required_ruby_version, as: :text - field :sha256, as: :text - field :required_rubygems_version, as: :text - end - end - - tab "API" do - panel do - field :info_checksum, as: :text - field :yanked_info_checksum, as: :text - end - end - - field :dependencies, as: :has_many - field :gem_download, as: :has_one, name: "Downloads" - field :deletion, as: :has_one - end -end diff --git a/app/avo/resources/web_hook.rb b/app/avo/resources/web_hook.rb new file mode 100644 index 00000000000..98ef03cdbef --- /dev/null +++ b/app/avo/resources/web_hook.rb @@ -0,0 +1,43 @@ +class Avo::Resources::WebHook < Avo::BaseResource + self.title = :id + self.includes = %i[user rubygem] + + def actions + action Avo::Actions::DeleteWebhook + end + + class EnabledFilter < Avo::Filters::ScopeBooleanFilter; end + class GlobalFilter < Avo::Filters::ScopeBooleanFilter; end + + def filters + filter EnabledFilter, arguments: { default: { enabled: true, disabled: false } } + filter GlobalFilter, arguments: { default: { global: true, specific: true } } + end + + def fields + field :id, as: :id, link_to_resource: true + + field :url, as: :text + field :enabled?, as: :boolean + field :failure_count, as: :number, sortable: true, index_text_align: :right + field :user, as: :belongs_to + field :rubygem, as: :belongs_to + field :global?, as: :boolean + + field :hook_relay_stream, as: :text do + stream_name = "webhook_id-#{record.id}" + link_to stream_name, "https://app.hookrelay.dev/hooks/#{ENV['HOOK_RELAY_STREAM_ID']}?started_at=P1W&stream=#{stream_name}" + end + + field :disabled_reason, as: :text + field :disabled_at, as: :date_time, sortable: true + field :last_success, as: :date_time, sortable: true + field :last_failure, as: :date_time, sortable: true + field :successes_since_last_failure, as: :number, sortable: true + field :failures_since_last_success, as: :number, sortable: true + + tabs style: :pills do + field :audits, as: :has_many + end + end +end diff --git a/app/avo/resources/web_hook_resource.rb b/app/avo/resources/web_hook_resource.rb deleted file mode 100644 index ee2c22d59f9..00000000000 --- a/app/avo/resources/web_hook_resource.rb +++ /dev/null @@ -1,35 +0,0 @@ -class WebHookResource < Avo::BaseResource - self.title = :id - self.includes = %i[user rubygem] - - action DeleteWebhook - class EnabledFilter < ScopeBooleanFilter; end - filter EnabledFilter, arguments: { default: { enabled: true, disabled: false } } - class GlobalFilter < ScopeBooleanFilter; end - filter GlobalFilter, arguments: { default: { global: true, specific: true } } - - field :id, as: :id, link_to_resource: true - - field :url, as: :text - field :enabled?, as: :boolean - field :failure_count, as: :number, sortable: true, index_text_align: :right - field :user, as: :belongs_to - field :rubygem, as: :belongs_to - field :global?, as: :boolean - - field :hook_relay_stream, as: :text do - stream_name = "webhook_id-#{model.id}" - link_to stream_name, "https://app.hookrelay.dev/hooks/#{ENV['HOOK_RELAY_STREAM_ID']}?started_at=P1W&stream=#{stream_name}" - end - - field :disabled_reason, as: :text - field :disabled_at, as: :date_time, sortable: true - field :last_success, as: :date_time, sortable: true - field :last_failure, as: :date_time, sortable: true - field :successes_since_last_failure, as: :number, sortable: true - field :failures_since_last_success, as: :number, sortable: true - - tabs style: :pills do - field :audits, as: :has_many - end -end diff --git a/app/avo/resources/webauthn_credential.rb b/app/avo/resources/webauthn_credential.rb new file mode 100644 index 00000000000..def6a1bcb20 --- /dev/null +++ b/app/avo/resources/webauthn_credential.rb @@ -0,0 +1,14 @@ +class Avo::Resources::WebauthnCredential < Avo::BaseResource + self.title = :id + self.includes = [] + + def fields + field :id, as: :id + + field :external_id, as: :text + field :public_key, as: :text + field :nickname, as: :text + field :sign_count, as: :number + field :user, as: :belongs_to + end +end diff --git a/app/avo/resources/webauthn_credential_resource.rb b/app/avo/resources/webauthn_credential_resource.rb deleted file mode 100644 index b6711b63eab..00000000000 --- a/app/avo/resources/webauthn_credential_resource.rb +++ /dev/null @@ -1,13 +0,0 @@ -class WebauthnCredentialResource < Avo::BaseResource - self.title = :id - self.includes = [] - - field :id, as: :id - # Fields generated from the model - field :external_id, as: :text - field :public_key, as: :text - field :nickname, as: :text - field :sign_count, as: :number - field :user, as: :belongs_to - # add fields here -end diff --git a/app/avo/resources/webauthn_verification.rb b/app/avo/resources/webauthn_verification.rb new file mode 100644 index 00000000000..48e509a1b76 --- /dev/null +++ b/app/avo/resources/webauthn_verification.rb @@ -0,0 +1,14 @@ +class Avo::Resources::WebauthnVerification < Avo::BaseResource + self.title = :id + self.includes = [] + + def fields + field :id, as: :id + + field :path_token, as: :text + field :path_token_expires_at, as: :date_time + field :otp, as: :text + field :otp_expires_at, as: :date_time + field :user, as: :belongs_to + end +end diff --git a/app/avo/resources/webauthn_verification_resource.rb b/app/avo/resources/webauthn_verification_resource.rb deleted file mode 100644 index 5834540ac89..00000000000 --- a/app/avo/resources/webauthn_verification_resource.rb +++ /dev/null @@ -1,13 +0,0 @@ -class WebauthnVerificationResource < Avo::BaseResource - self.title = :id - self.includes = [] - - field :id, as: :id - # Fields generated from the model - field :path_token, as: :text - field :path_token_expires_at, as: :date_time - field :otp, as: :text - field :otp_expires_at, as: :date_time - field :user, as: :belongs_to - # add fields here -end diff --git a/config/initializers/avo.rb b/config/initializers/avo.rb index 2dd78212595..2a2bd1f9ad1 100644 --- a/config/initializers/avo.rb +++ b/config/initializers/avo.rb @@ -7,7 +7,6 @@ config.home_path = "/admin/dashboards/dashy" ## == Licensing == - # config.license = 'pro' # change this to 'pro' when you add the license key config.license_key = ENV['AVO_LICENSE_KEY'] ## == Set the context == @@ -136,7 +135,7 @@ Rails.configuration.to_prepare do Avo::ApplicationController.include GitHubOAuthable Avo::BaseController.prepend AvoAuditable - # Avo::BaseResource.include Concerns::AvoAuditableResource + Avo::BaseResource.include Avo::Resources::Concerns::AvoAuditableResource Avo::ApplicationController.content_security_policy do |policy| policy.style_src :self, "https://fonts.googleapis.com", :unsafe_inline diff --git a/config/initializers/prosopite.rb b/config/initializers/prosopite.rb index 95e7e0208d6..cf2651df06f 100644 --- a/config/initializers/prosopite.rb +++ b/config/initializers/prosopite.rb @@ -13,6 +13,7 @@ # avo auditing potentially loads things multiple times, but it will be bounded by the size of the audit "app/avo/actions/base_action.rb", "app/components/avo/fields/audited_changes_field/show_component.html.erb", + "app/components/avo/views/resource_index_component.html.erb", # calls count for each owner, AR doesn't yet allow preloading aggregates "app/views/ownership_requests/_ownership_request.html.erb" diff --git a/lib/admin/authorization_client.rb b/lib/admin/authorization_client.rb index 6a95c709438..27d0718eb2f 100644 --- a/lib/admin/authorization_client.rb +++ b/lib/admin/authorization_client.rb @@ -1,6 +1,8 @@ +return unless defined?(Avo::Pro) + # This class is the same as the default pundit authorization client. # It just adds the admin scope automatically so that Avo pundit policies can be kept separate. -class Admin::AuthorizationClient < Avo::Services::AuthorizationClients::PunditClient +class Admin::AuthorizationClient < Avo::Pro::Authorization::Clients::PunditClient def authorize(user, record, action, policy_class: nil) # After https://github.com/avo-hq/avo/pull/2827 lands, we can hopefully remove this hack policy_class ||= Admin::GitHubUserPolicy if record == Admin::GitHubUser diff --git a/test/test_helper.rb b/test/test_helper.rb index f3cbb1699bc..94a99a0557c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -38,7 +38,7 @@ # setup license early since some tests are testing Avo outside of requests # and license is set with first request -Avo::App.license = Avo::Licensing::LicenseManager.new(Avo::Licensing::HQ.new.response).license +Avo::Current.license = Avo::Licensing::LicenseManager.new(Avo::Licensing::HQ.new.response).license WebMock.disable_net_connect!( allow_localhost: true, @@ -242,6 +242,8 @@ class SystemTest < ActionDispatch::IntegrationTest class AdminPolicyTestCase < ActiveSupport::TestCase def setup + skip "avo-pro needed to run this test" unless defined?(Avo::Pro) + @authorization_client = Admin::AuthorizationClient.new end diff --git a/test/unit/avo/actions/base_action_test.rb b/test/unit/avo/actions/base_action_test.rb index fd5f46600a5..73d36957aa0 100644 --- a/test/unit/avo/actions/base_action_test.rb +++ b/test/unit/avo/actions/base_action_test.rb @@ -1,23 +1,23 @@ require "test_helper" class BaseActionTest < ActiveSupport::TestCase - class DestroyerAction < BaseAction - class ActionHandler < ActionHandler + class DestroyerAction < Avo::Actions::ApplicationAction + class ActionHandler < Avo::Actions::ActionHandler def handle_model(model) model.destroy! end end end - class EmptyAction < BaseAction - class ActionHandler < ActionHandler + class EmptyAction < Avo::Actions::ApplicationAction + class ActionHandler < Avo::Actions::ActionHandler def handle_model(model) end end end - class WebHookCreateAction < BaseAction - class ActionHandler < BaseAction::ActionHandler + class WebHookCreateAction < Avo::Actions::ApplicationAction + class ActionHandler < Avo::Actions::ActionHandler def handle_model(user) user.web_hooks.create(url: "https://example.com/path") end @@ -32,7 +32,7 @@ def handle_model(user) @view_context.stubs(:avo).returns(@avo) @avo.stubs(:resources_audit_path).returns("resources_audit_path") - ::Avo::App.init request: nil, context: nil, current_user: nil, view_context: @view_context, params: {} + ::Avo.init end test "handles errors" do @@ -41,7 +41,7 @@ def each raise "Cannot enumerate" end end.new - action = BaseAction.new + action = Avo::Actions::ApplicationAction.new args = { fields: {