diff --git a/Gemfile b/Gemfile index a97eac7..7e34274 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,7 @@ gem "stimulus-rails" gem "jbuilder" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ windows jruby ] @@ -50,6 +50,11 @@ gem "thruster", require: false group :development do # Use console on exceptions pages [https://github.com/rails/web-console] gem "web-console" + + gem "rubocop-rails", require: false + gem "rubocop-performance", require: false + gem "rubocop-rspec", require: false + gem "rubocop-rspec_rails", require: false end group :development, :test do @@ -68,12 +73,3 @@ group :development, :test do gem "rspec-rails", "~> 8.0.0" end -group :development do - # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" - - gem "rubocop-rails", require: false - gem "rubocop-performance", require: false - gem "rubocop-rspec", require: false - gem "rubocop-rspec_rails", require: false -end diff --git a/Gemfile.lock b/Gemfile.lock index ba4e61f..6ca3d03 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,6 +74,7 @@ GEM uri (>= 0.13.1) ast (2.4.3) base64 (0.3.0) + bcrypt (3.1.20) bcrypt_pbkdf (1.1.1) bcrypt_pbkdf (1.1.1-arm64-darwin) bcrypt_pbkdf (1.1.1-x86_64-darwin) @@ -401,6 +402,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap brakeman debug @@ -411,13 +413,10 @@ DEPENDENCIES puma (>= 5.0) rails (~> 8.0.2) rails_db - rspec-rails (~> 8.0.0) - rubocop rubocop-performance rubocop-rails - rubocop-rails-omakase rubocop-rspec rubocop-rspec_rails diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0d95db2..a26e8b4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,23 @@ class ApplicationController < ActionController::Base - # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. - allow_browser versions: :modern + helper_method :current_user, :logged_in? + + def current_user + @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] + end + + def logged_in? + current_user.present? + end + + private + + def require_admin + unless current_user&.role == "admin" + flash[:alert] = "You do not have permission to do that." + redirect_to root_path + end + end + + # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. + allow_browser versions: :modern end diff --git a/app/controllers/artists_controller.rb b/app/controllers/artists_controller.rb index b1e4610..a0c2e29 100644 --- a/app/controllers/artists_controller.rb +++ b/app/controllers/artists_controller.rb @@ -1,6 +1,6 @@ class ArtistsController < ApplicationController def index - @artists = Artist.all + @artists = Artist.alphabetical end def show @@ -14,7 +14,7 @@ def new def create @artist = Artist.new(artist_params) if @artist.save - redirect_to @artist, notice: "Artist Created" + redirect_to new_track_path(artist_id: @artist.id), notice: "Artist Created" else render :new, status: :unprocessable_entity end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..095eeb1 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,22 @@ +class SessionsController < ApplicationController + def new + # renders the login form + end + + def create + user = User.find_by(username: params[:username]) + if user&.authenticate(params[:password]) + session[:user_id] = user.id + session[:role] = user.role + redirect_to root_path, notice: "Logged in as #{user.username}" + else + flash.now[:alert] = "Invalid username or password" + render :new, status: :unprocessable_entity + end + end + + def destroy + reset_session + redirect_to root_path, notice: "Logged out" + end +end diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index 77d3e67..8e6eeb7 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -1,4 +1,5 @@ class TracksController < ApplicationController + before_action :require_admin, only: [ :destroy ] def index @tracks = Track.all end @@ -9,6 +10,10 @@ def show def new @track = Track.new + @artists = Artist.alphabetical + if params[:artist_id].present? + @track.artist_id = params[:artist_id] + end end def create diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000..309f8b2 --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/models/artist.rb b/app/models/artist.rb index 8083841..563c36b 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -3,10 +3,13 @@ class Artist < ApplicationRecord validates :name, presence: true + # alpha scope + scope :alphabetical, -> { order("LOWER(name) ASC") } + # logic for sample connections, artist + method + each loop def sampled_by Track.joins(:artist, :samples_used) - .where(samples: { source_track_id: tracks.select(:id) }) - .select("tracks.title AS track_title, artists.name AS artist_name") + .where(samples: { source_track_id: tracks.select(:id) }) + .select("tracks.title AS track_title, artists.name AS artist_name") end end diff --git a/app/models/track.rb b/app/models/track.rb index a617471..07954bc 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -1,5 +1,5 @@ class Track < ApplicationRecord - belongs_to :user, optional: true + belongs_to :user belongs_to :artist has_many :comments, dependent: :destroy diff --git a/app/models/user.rb b/app/models/user.rb index 1f9e77f..ac6aa84 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,8 @@ class User < ApplicationRecord has_many :comments # TODO gameplan user.delete, what happens to their entries and comments. + has_secure_password + validates :email, presence: true, uniqueness: true validates :username, presence: true, uniqueness: true diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 27151dc..d5d1cd2 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -22,7 +22,22 @@ <%= javascript_importmap_tags %> -
- <%= yield %> - + + <% if flash[:notice] %> +<%= flash[:notice] %>
+ <% end %> + + <% if flash[:alert] %> +<%= flash[:alert] %>
+ <% end %> + + <% if logged_in? %> +Logged in as <%= current_user.username %>
+ <%= button_to "Logout", logout_path, method: :delete %> + <% else %> + <%= link_to "Login", login_path %> + <% end %> + + <%= yield %> +