diff --git a/Gemfile b/Gemfile index d1d27c6..d916461 100644 --- a/Gemfile +++ b/Gemfile @@ -33,7 +33,7 @@ gem "jbuilder" # gem "kredis" # 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 ] diff --git a/Gemfile.lock b/Gemfile.lock index 4caa16a..052182c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,6 +78,7 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) + bcrypt (3.1.20) bigdecimal (3.1.8) bindex (0.8.1) bootsnap (1.18.4) @@ -245,6 +246,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap capybara debug diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d1..039cdee 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,18 @@ class ApplicationController < ActionController::Base + 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.nil? + end + + def require_user + unless logged_in? + flash[:alert] = "You must be logged in first. Please visit the signup page to create an account." + redirect_to login_path + end + end end diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 151eac9..61fa451 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -1,5 +1,5 @@ class ArticlesController < ApplicationController - http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show] + before_action :require_user, except: [:show, :index] def index @articles = Article.all @@ -15,6 +15,7 @@ class ArticlesController < ApplicationController def create @article = Article.new(article_params) + @article.user_id = current_user.id if @article.save redirect_to @article diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 9165327..9ea649c 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,21 +1,31 @@ class CommentsController < ApplicationController - http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy + before_action :require_user def create @article = Article.find(params[:article_id]) - @comment = @article.comments.create(comment_params) + @comment = @article.comments.new(comment_params) + @comment.commenter = current_user.username + + if @comment.save + flash[:notice] = "Comment added successfully." + else + flash[:alert] = "Failed to add comment." + end + redirect_to article_path(@article) end def destroy @article = Article.find(params[:article_id]) @comment = @article.comments.find(params[:id]) - comment.destroy + if @article.user_id == current_user.id || @comment.commenter == current_user.username + @comment.destroy + end redirect_to article_path(@article), status: :see_other end private def comment_params - params.require(:comment).permit(:commenter, :body, :status) + params.require(:comment).permit(:body, :status) end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..4e77811 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,23 @@ +class SessionsController < ApplicationController + def new + end + + def create + user = User.find_by(email: params[:email].downcase) + if user && user.authenticate(params[:password]) + session[:user_id] = user.id + flash[:notice] = "Logged in successfully." + redirect_to root_path + else + flash[:alert] = "Invalid email or password" + render :new + end + end + + def destroy + session[:user_id] = nil + reset_session + flash[:notice] = "Logged out successfully." + redirect_to root_path + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..ea252dc --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,22 @@ +class UsersController < ApplicationController + def new + @user = User.new + end + + def create + @user = User.new(user_params) + if @user.save + session[:user_id] = @user.id + flash[:notice] = "Welcome! You have successfully signed up." + redirect_to root_path + else + render :new + end + end + + private + + def user_params + params.require(:user).permit(:username, :email, :password, :password_confirmation) + end +end 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/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/article.rb b/app/models/article.rb index 57ec8c1..f4ff4d5 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -1,7 +1,7 @@ class Article < ApplicationRecord include Visible - belongs_to: :user + belongs_to :user has_many :comments, dependent: :destroy validates :title, presence: true diff --git a/app/models/user.rb b/app/models/user.rb index 9ecd5e0..3c0d0a3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,7 @@ class User < ApplicationRecord - has_many :articles, dependent: :destroy - + has_many :articles, dependent: :destroy has_secure_password + + validates :email, presence: true, uniqueness: true + validates :password, presence: true, length: { minimum: 6 } end diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb index 7eb810a..8fb5867 100644 --- a/app/views/articles/index.html.erb +++ b/app/views/articles/index.html.erb @@ -1,3 +1,12 @@ +<% if logged_in? %> +
Logged in as <%= current_user.username %>
+<%= link_to "Log out", logout_path, data: { + turbo_method: :delete + } %>
+<% else %> +<%= link_to "Log in", login_path %> or <%= link_to "Sign up", signup_path %>
+<% end %> +<%= @article.body %>
-
- <%= form.label :commenter %>
- <%= form.text_field :commenter %>
-
- <%= form.label :body %>
- <%= form.text_area :body %>
-
- <%= form.label :status %>
- <%= form.select :status, Visible::VALID_STATUSES, selected: 'public' %>
-
- <%= form.submit %>
-
+ <%= form.label :body %>
+ <%= form.text_area :body %>
+
+ <%= form.label :status %>
+ <%= form.select :status, Visible::VALID_STATUSES, selected: 'public' %>
+
+ <%= form.submit %>
+
Find me in app/views/sessions/create.html.erb
diff --git a/app/views/sessions/destroy.html.erb b/app/views/sessions/destroy.html.erb new file mode 100644 index 0000000..d75237d --- /dev/null +++ b/app/views/sessions/destroy.html.erb @@ -0,0 +1,2 @@ +Find me in app/views/sessions/destroy.html.erb
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..42c1913 --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,17 @@ +