From 062047263888c8e3ad15a5901f155121a1078357 Mon Sep 17 00:00:00 2001 From: "Jesse C. Fisher" Date: Wed, 10 May 2023 14:15:43 +0000 Subject: [PATCH] Add private urls to tables --- Gemfile | 1 + Gemfile.lock | 3 + app/assets/stylesheets/application.css.sass | 3 + app/assets/stylesheets/game.css.sass | 2 + app/assets/stylesheets/tables.css.sass | 4 + app/controllers/tables_controller.rb | 10 +- app/models/table.rb | 4 +- app/policies/table_policy.rb | 12 ++ app/views/layouts/_footer.html.haml | 2 +- app/views/tables/show.html.haml | 17 ++- config/initializers/friendly_id.rb | 107 ++++++++++++++++++ ...0230505072838_add_skyspace_url_to_table.rb | 5 + .../20230510103640_add_slug_to_tables.rb | 6 + ...20230510103647_create_friendly_id_slugs.rb | 21 ++++ db/schema.rb | 16 ++- 15 files changed, 201 insertions(+), 12 deletions(-) create mode 100644 config/initializers/friendly_id.rb create mode 100644 db/migrate/20230505072838_add_skyspace_url_to_table.rb create mode 100644 db/migrate/20230510103640_add_slug_to_tables.rb create mode 100644 db/migrate/20230510103647_create_friendly_id_slugs.rb diff --git a/Gemfile b/Gemfile index be005a7f..9a4547db 100644 --- a/Gemfile +++ b/Gemfile @@ -76,3 +76,4 @@ group :test, :staging do gem 'simplecov', :require => false end gem 'capybara-screenshot', :group => :test +gem 'friendly_id', '~> 5.4.0' diff --git a/Gemfile.lock b/Gemfile.lock index 6e924806..7750eea4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -161,6 +161,8 @@ GEM i18n (>= 1.6, < 2) ffi (1.15.4) formatador (0.3.0) + friendly_id (5.4.2) + activerecord (>= 4.0.0) globalid (0.5.2) activesupport (>= 5.0) guard (2.18.0) @@ -455,6 +457,7 @@ DEPENDENCIES ed25519 factory_girl_rails faker + friendly_id (~> 5.4.0) guard-bundler guard-ctags-bundler guard-livereload diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass index b5384b86..a8a6af88 100644 --- a/app/assets/stylesheets/application.css.sass +++ b/app/assets/stylesheets/application.css.sass @@ -160,3 +160,6 @@ footer #skyspaces width: 100% height: 100% + +.hide + display: none diff --git a/app/assets/stylesheets/game.css.sass b/app/assets/stylesheets/game.css.sass index 25e8cb4d..35112f14 100644 --- a/app/assets/stylesheets/game.css.sass +++ b/app/assets/stylesheets/game.css.sass @@ -30,6 +30,8 @@ button, input[type=submit] font-size: 4vmin + &.smallbtn + font-size: 2vmin #table-component, #game-component-container-container diff --git a/app/assets/stylesheets/tables.css.sass b/app/assets/stylesheets/tables.css.sass index 37631116..a78da048 100644 --- a/app/assets/stylesheets/tables.css.sass +++ b/app/assets/stylesheets/tables.css.sass @@ -2,6 +2,10 @@ width: 100% height: 100% +.owner-controls + form + display: inline-block + #table-controls text-align: right padding: 0 1em diff --git a/app/controllers/tables_controller.rb b/app/controllers/tables_controller.rb index 15391309..e0e551d0 100644 --- a/app/controllers/tables_controller.rb +++ b/app/controllers/tables_controller.rb @@ -60,17 +60,18 @@ class TablesController < ApplicationController # GET /tables/new def new - @table = Table.new + authorize @table = Table.new end # GET /tables/1/edit def edit + authorize @table end # POST /tables # POST /tables.json def create - @table = Table.new(table_params) + authorize @table = Table.new(table_params) respond_to do |format| if @table.save @@ -86,6 +87,7 @@ class TablesController < ApplicationController # PATCH/PUT /tables/1 # PATCH/PUT /tables/1.json def update + authorize @table respond_to do |format| if @table.update(table_params) format.html { redirect_to @table, notice: 'Table was successfully updated.' } @@ -100,6 +102,7 @@ class TablesController < ApplicationController # DELETE /tables/1 # DELETE /tables/1.json def destroy + authorize @table @table.destroy respond_to do |format| format.html { redirect_to tables_url, notice: 'Table was successfully destroyed.' } @@ -110,7 +113,8 @@ class TablesController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_table - @table = Table.find(params[:id]) + # @table = Table.find(params[:id]) + @table = Table.friendly.find(params[:id]) @game = @table.current_game @seats = @table.seats.order(:id) end diff --git a/app/models/table.rb b/app/models/table.rb index 88537421..58bd6557 100644 --- a/app/models/table.rb +++ b/app/models/table.rb @@ -1,4 +1,6 @@ class Table < ActiveRecord::Base + extend FriendlyId + friendly_id :title, use: :slugged #TODO has_many :moderators has_many :seats has_many :users, through: :seats @@ -19,7 +21,7 @@ class Table < ActiveRecord::Base # } scope :play_now, lambda { |user| # where(status:nil).joins("LEFT OUTER JOIN players ON players.game_id = games.id").group("games.id").having("count(players) < 4").last || Table.create(title: "Game " + user.soft_token[0..4]) - where(game:nil).last || Table.create(title: "Table " + user.soft_token[0..4]) + where(game:nil).last || Table.create(title: user.soft_token[0..4]) } def user_count diff --git a/app/policies/table_policy.rb b/app/policies/table_policy.rb index df18a02b..2ed00da1 100644 --- a/app/policies/table_policy.rb +++ b/app/policies/table_policy.rb @@ -14,6 +14,18 @@ class TablePolicy @current_user.admin? || @current_user == @user end + def create? + @current_user.admin? + end + + def new? + @current_user.admin? + end + + def edit? + @current_user.admin? + end + def update? @current_user.admin? # TODO: Allow table owner to edit || @table.owner == @current_user end diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index da597f3d..080fa497 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -1 +1 @@ -= link_to (image_tag "telegram-logo.png", height: 32, width: 32), "https://t.me/+IEp-tAetjYozYWM5" +-# = link_to (image_tag "telegram-logo.png", height: 32, width: 32), "https://t.me/+IEp-tAetjYozYWM5" diff --git a/app/views/tables/show.html.haml b/app/views/tables/show.html.haml index b11c63c8..39080149 100644 --- a/app/views/tables/show.html.haml +++ b/app/views/tables/show.html.haml @@ -1,12 +1,14 @@ -- if policy(@table).update? - .owner-controls - = link_to 'Edit', edit_table_path(@table) - = link_to 'Destroy', game, :method => :delete, :data => { :confirm => 'Are you sure?' } - -# #table-component-container-container= react_component 'Table', props = {url: "#{table_path @table}"}, html_options = {id: "table-component-container"} #table-component - %p= @table.title + %p + Table: + = @table.title + + - if policy(@table).update? + .owner-controls + = button_to 'Rename', edit_table_path(@table), class: "smallbtn", method: :get + = button_to 'Delete', @game, :method => :delete, :data => { :confirm => 'Are you sure?' }, class: "smallbtn" - if @game.already_has?(current_user) - if @game.startable? @@ -57,3 +59,6 @@ :javascript var soft_token = "#{current_user.soft_token}"; -# = javascript_include_tag 'table-loader' + +-# - if @table.skyspace_url + %iframe#skyspaces{allow:"camera #{@table.skyspace_url}; microphone #{@table.skyspace_url}", src: "#{@table.skyspace_url}"} diff --git a/config/initializers/friendly_id.rb b/config/initializers/friendly_id.rb new file mode 100644 index 00000000..d557afe8 --- /dev/null +++ b/config/initializers/friendly_id.rb @@ -0,0 +1,107 @@ +# FriendlyId Global Configuration +# +# Use this to set up shared configuration options for your entire application. +# Any of the configuration options shown here can also be applied to single +# models by passing arguments to the `friendly_id` class method or defining +# methods in your model. +# +# To learn more, check out the guide: +# +# http://norman.github.io/friendly_id/file.Guide.html + +FriendlyId.defaults do |config| + # ## Reserved Words + # + # Some words could conflict with Rails's routes when used as slugs, or are + # undesirable to allow as slugs. Edit this list as needed for your app. + config.use :reserved + + config.reserved_words = %w(new edit index session login logout users admin + stylesheets assets javascripts images) + + # This adds an option to treat reserved words as conflicts rather than exceptions. + # When there is no good candidate, a UUID will be appended, matching the existing + # conflict behavior. + + # config.treat_reserved_as_conflict = true + + # ## Friendly Finders + # + # Uncomment this to use friendly finders in all models. By default, if + # you wish to find a record by its friendly id, you must do: + # + # MyModel.friendly.find('foo') + # + # If you uncomment this, you can do: + # + # MyModel.find('foo') + # + # This is significantly more convenient but may not be appropriate for + # all applications, so you must explicity opt-in to this behavior. You can + # always also configure it on a per-model basis if you prefer. + # + # Something else to consider is that using the :finders addon boosts + # performance because it will avoid Rails-internal code that makes runtime + # calls to `Module.extend`. + # + # config.use :finders + # + # ## Slugs + # + # Most applications will use the :slugged module everywhere. If you wish + # to do so, uncomment the following line. + # + # config.use :slugged + # + # By default, FriendlyId's :slugged addon expects the slug column to be named + # 'slug', but you can change it if you wish. + # + # config.slug_column = 'slug' + # + # By default, slug has no size limit, but you can change it if you wish. + # + # config.slug_limit = 255 + # + # When FriendlyId can not generate a unique ID from your base method, it appends + # a UUID, separated by a single dash. You can configure the character used as the + # separator. If you're upgrading from FriendlyId 4, you may wish to replace this + # with two dashes. + # + # config.sequence_separator = '-' + # + # Note that you must use the :slugged addon **prior** to the line which + # configures the sequence separator, or else FriendlyId will raise an undefined + # method error. + # + # ## Tips and Tricks + # + # ### Controlling when slugs are generated + # + # As of FriendlyId 5.0, new slugs are generated only when the slug field is + # nil, but if you're using a column as your base method can change this + # behavior by overriding the `should_generate_new_friendly_id?` method that + # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave + # more like 4.0. + # Note: Use(include) Slugged module in the config if using the anonymous module. + # If you have `friendly_id :name, use: slugged` in the model, Slugged module + # is included after the anonymous module defined in the initializer, so it + # overrides the `should_generate_new_friendly_id?` method from the anonymous module. + # + # config.use :slugged + # config.use Module.new { + # def should_generate_new_friendly_id? + # slug.blank? || _changed? + # end + # } + # + # FriendlyId uses Rails's `parameterize` method to generate slugs, but for + # languages that don't use the Roman alphabet, that's not usually sufficient. + # Here we use the Babosa library to transliterate Russian Cyrillic slugs to + # ASCII. If you use this, don't forget to add "babosa" to your Gemfile. + # + # config.use Module.new { + # def normalize_friendly_id(text) + # text.to_slug.normalize! :transliterations => [:russian, :latin] + # end + # } +end diff --git a/db/migrate/20230505072838_add_skyspace_url_to_table.rb b/db/migrate/20230505072838_add_skyspace_url_to_table.rb new file mode 100644 index 00000000..e503a9dc --- /dev/null +++ b/db/migrate/20230505072838_add_skyspace_url_to_table.rb @@ -0,0 +1,5 @@ +class AddSkyspaceUrlToTable < ActiveRecord::Migration[5.2] + def change + add_column :tables, :skyspace_url, :string + end +end diff --git a/db/migrate/20230510103640_add_slug_to_tables.rb b/db/migrate/20230510103640_add_slug_to_tables.rb new file mode 100644 index 00000000..33f2d3c4 --- /dev/null +++ b/db/migrate/20230510103640_add_slug_to_tables.rb @@ -0,0 +1,6 @@ +class AddSlugToTables < ActiveRecord::Migration[5.2] + def change + add_column :tables, :slug, :string + add_index :tables, :slug, unique: true + end +end diff --git a/db/migrate/20230510103647_create_friendly_id_slugs.rb b/db/migrate/20230510103647_create_friendly_id_slugs.rb new file mode 100644 index 00000000..aefc9911 --- /dev/null +++ b/db/migrate/20230510103647_create_friendly_id_slugs.rb @@ -0,0 +1,21 @@ +MIGRATION_CLASS = + if ActiveRecord::VERSION::MAJOR >= 5 + ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"] + else + ActiveRecord::Migration + end + +class CreateFriendlyIdSlugs < MIGRATION_CLASS + def change + create_table :friendly_id_slugs do |t| + t.string :slug, :null => false + t.integer :sluggable_id, :null => false + t.string :sluggable_type, :limit => 50 + t.string :scope + t.datetime :created_at + end + add_index :friendly_id_slugs, [:sluggable_type, :sluggable_id] + add_index :friendly_id_slugs, [:slug, :sluggable_type], length: { slug: 140, sluggable_type: 50 } + add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], length: { slug: 70, sluggable_type: 50, scope: 70 }, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 1befbadb..14b1266f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,22 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_08_045859) do +ActiveRecord::Schema.define(version: 2023_05_10_103647) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "friendly_id_slugs", force: :cascade do |t| + t.string "slug", null: false + t.integer "sluggable_id", null: false + t.string "sluggable_type", limit: 50 + t.string "scope" + t.datetime "created_at" + t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true + t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type" + t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id" + end + create_table "games", force: :cascade do |t| t.string "title" t.datetime "created_at" @@ -85,6 +96,9 @@ ActiveRecord::Schema.define(version: 2021_11_08_045859) do t.datetime "created_at" t.datetime "updated_at" t.integer "current_game_id" + t.string "skyspace_url" + t.string "slug" + t.index ["slug"], name: "index_tables_on_slug", unique: true end create_table "users", force: :cascade do |t|