From 423cd86abc14ceded7f1b9d480c6bd1fcf671036 Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 15:18:50 +0100 Subject: [PATCH 1/7] created db users, sessions, attributes, models validations, post routes, controllers create functions --- app/controllers/sessions_controller.rb | 19 +++++++++++++++++- app/controllers/users_controller.rb | 20 +++++++++++++++++++ app/models/session.rb | 7 +++++++ app/models/user.rb | 8 ++++++++ config/routes.rb | 4 ++-- db/migrate/20220518131947_create_users.rb | 8 ++++++++ .../20220518132107_add_attributes_to_users.rb | 8 ++++++++ db/migrate/20220518135038_create_sessions.rb | 8 ++++++++ ...220518135219_add_attributes_to_sessions.rb | 6 ++++++ .../20220518135320_add_user_id_to_sessions.rb | 5 +++++ db/schema.rb | 20 ++++++++++++++++++- 11 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20220518131947_create_users.rb create mode 100644 db/migrate/20220518132107_add_attributes_to_users.rb create mode 100644 db/migrate/20220518135038_create_sessions.rb create mode 100644 db/migrate/20220518135219_add_attributes_to_sessions.rb create mode 100644 db/migrate/20220518135320_add_user_id_to_sessions.rb diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b0435f5a..7ee2dab8 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,3 +1,20 @@ class SessionsController < ApplicationController - + def create + @user = User.find_by(username: params[:user][:username]) + if @user and @user.password == params[:user][:password] + session = @user.sessions.create + cookies.permanent.signed[:twitter_session_token] = { + value: session.token, + httponly: true + } + render json: { + success: true + } + else + render json: { + success: false + } + end + end +end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3f7e4615..86c103ba 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,3 +1,23 @@ class UsersController < ApplicationController + def create + @user = User.new(user_params) + if @user.save + render json: { + user: { + username: @user.username, + email: @user.email, + password: @user.password + } + } + else + render json: { + success: false + } + end + end + private + def user_params + params.require(:user).permit(:username, :email, :password) + end end diff --git a/app/models/session.rb b/app/models/session.rb index 557f8903..c5446f46 100644 --- a/app/models/session.rb +++ b/app/models/session.rb @@ -1,3 +1,10 @@ class Session < ApplicationRecord + belongs_to :user + before_validation :generate_session_token + + private + def generate_session_token + self.token = SecureRandom.urlsafe_base64 + end end diff --git a/app/models/user.rb b/app/models/user.rb index a02d9a68..eb20e277 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,11 @@ class User < ApplicationRecord + validates :username, presence: true, length: { minimum: 3, maximum: 64 } + validates :email, presence: true, length: { minimum: 5, maximum: 500 } + validates :password, presence: true, length: { minimum: 8, maximum: 64 } + validates_uniqueness_of :username + validates_uniqueness_of :email + + has_many :sessions + has_many :tweets end diff --git a/config/routes.rb b/config/routes.rb index 4405fd14..51e96f20 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,10 +4,10 @@ # USERS - + post '/users' => 'users#create' # SESSIONS - + post '/sessions' => 'sessions#create' # TWEETS diff --git a/db/migrate/20220518131947_create_users.rb b/db/migrate/20220518131947_create_users.rb new file mode 100644 index 00000000..a31e6838 --- /dev/null +++ b/db/migrate/20220518131947_create_users.rb @@ -0,0 +1,8 @@ +class CreateUsers < ActiveRecord::Migration[6.1] + def change + create_table :users do |t| + + t.timestamps + end + end +end diff --git a/db/migrate/20220518132107_add_attributes_to_users.rb b/db/migrate/20220518132107_add_attributes_to_users.rb new file mode 100644 index 00000000..af4e9d1a --- /dev/null +++ b/db/migrate/20220518132107_add_attributes_to_users.rb @@ -0,0 +1,8 @@ +class AddAttributesToUsers < ActiveRecord::Migration[6.1] + def change + add_column :users, :username, :string + add_column :users, :email, :string + add_column :users, :password, :string + add_column :users, :timestamps, :datetime + end +end diff --git a/db/migrate/20220518135038_create_sessions.rb b/db/migrate/20220518135038_create_sessions.rb new file mode 100644 index 00000000..93758cde --- /dev/null +++ b/db/migrate/20220518135038_create_sessions.rb @@ -0,0 +1,8 @@ +class CreateSessions < ActiveRecord::Migration[6.1] + def change + create_table :sessions do |t| + + t.timestamps + end + end +end diff --git a/db/migrate/20220518135219_add_attributes_to_sessions.rb b/db/migrate/20220518135219_add_attributes_to_sessions.rb new file mode 100644 index 00000000..575b27fd --- /dev/null +++ b/db/migrate/20220518135219_add_attributes_to_sessions.rb @@ -0,0 +1,6 @@ +class AddAttributesToSessions < ActiveRecord::Migration[6.1] + def change + add_column :sessions, :token, :string + add_column :sessions, :timestamps, :datetime + end +end diff --git a/db/migrate/20220518135320_add_user_id_to_sessions.rb b/db/migrate/20220518135320_add_user_id_to_sessions.rb new file mode 100644 index 00000000..64b27f27 --- /dev/null +++ b/db/migrate/20220518135320_add_user_id_to_sessions.rb @@ -0,0 +1,5 @@ +class AddUserIdToSessions < ActiveRecord::Migration[6.1] + def change + add_belongs_to :sessions, :user + end +end diff --git a/db/schema.rb b/db/schema.rb index 77bcf0fe..f5d07f62 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,6 +10,24 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 2022_05_18_135320) do + + create_table "sessions", force: :cascade do |t| + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "token" + t.datetime "timestamps" + t.integer "user_id" + t.index ["user_id"], name: "index_sessions_on_user_id" + end + + create_table "users", force: :cascade do |t| + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "username" + t.string "email" + t.string "password" + t.datetime "timestamps" + end end From f194e2343c4a20eafe67a87b839052a5ca47cf9f Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 16:06:18 +0100 Subject: [PATCH 2/7] models validated - users, sessions, tweets; controllers validated - users --- app/controllers/sessions_controller.rb | 2 +- app/controllers/tweets_controller.rb | 2 +- app/controllers/users_controller.rb | 1 - app/models/session.rb | 5 ++--- app/models/tweet.rb | 2 ++ db/migrate/20220518144236_create_tweets.rb | 8 ++++++++ db/migrate/20220518144309_add_attributes_to_tweets.rb | 6 ++++++ db/migrate/20220518144443_add_user_id_to_tweets.rb | 5 +++++ db/schema.rb | 10 +++++++++- 9 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20220518144236_create_tweets.rb create mode 100644 db/migrate/20220518144309_add_attributes_to_tweets.rb create mode 100644 db/migrate/20220518144443_add_user_id_to_tweets.rb diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7ee2dab8..350264be 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -17,4 +17,4 @@ def create end end end -end + diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index 1c4bc871..b5bda8cc 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -1,3 +1,3 @@ class TweetsController < ApplicationController - + end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 86c103ba..e801f179 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -6,7 +6,6 @@ def create user: { username: @user.username, email: @user.email, - password: @user.password } } else diff --git a/app/models/session.rb b/app/models/session.rb index c5446f46..f9df615e 100644 --- a/app/models/session.rb +++ b/app/models/session.rb @@ -1,8 +1,7 @@ class Session < ApplicationRecord - belongs_to :user - + belongs_to :user, required:true before_validation :generate_session_token - + private def generate_session_token self.token = SecureRandom.urlsafe_base64 diff --git a/app/models/tweet.rb b/app/models/tweet.rb index 68958ab1..0b6efed3 100644 --- a/app/models/tweet.rb +++ b/app/models/tweet.rb @@ -1,3 +1,5 @@ class Tweet < ApplicationRecord + belongs_to :user, required:true + validates :message, length: { maximum: 140 }, presence: true end diff --git a/db/migrate/20220518144236_create_tweets.rb b/db/migrate/20220518144236_create_tweets.rb new file mode 100644 index 00000000..95a9a4bf --- /dev/null +++ b/db/migrate/20220518144236_create_tweets.rb @@ -0,0 +1,8 @@ +class CreateTweets < ActiveRecord::Migration[6.1] + def change + create_table :tweets do |t| + + t.timestamps + end + end +end diff --git a/db/migrate/20220518144309_add_attributes_to_tweets.rb b/db/migrate/20220518144309_add_attributes_to_tweets.rb new file mode 100644 index 00000000..9d2941e1 --- /dev/null +++ b/db/migrate/20220518144309_add_attributes_to_tweets.rb @@ -0,0 +1,6 @@ +class AddAttributesToTweets < ActiveRecord::Migration[6.1] + def change + add_column :tweets, :message, :string + add_column :tweets, :timestamps, :datetime + end +end diff --git a/db/migrate/20220518144443_add_user_id_to_tweets.rb b/db/migrate/20220518144443_add_user_id_to_tweets.rb new file mode 100644 index 00000000..df623602 --- /dev/null +++ b/db/migrate/20220518144443_add_user_id_to_tweets.rb @@ -0,0 +1,5 @@ +class AddUserIdToTweets < ActiveRecord::Migration[6.1] + def change + add_column :tweets, :user_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index f5d07f62..84673c3e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_05_18_135320) do +ActiveRecord::Schema.define(version: 2022_05_18_144443) do create_table "sessions", force: :cascade do |t| t.datetime "created_at", precision: 6, null: false @@ -21,6 +21,14 @@ t.index ["user_id"], name: "index_sessions_on_user_id" end + create_table "tweets", force: :cascade do |t| + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "message" + t.datetime "timestamps" + t.integer "user_id" + end + create_table "users", force: :cascade do |t| t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false From 4786e56e66c7cd2601b5272da472b28e15aa1624 Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 16:25:48 +0100 Subject: [PATCH 3/7] Create Users and Sessions login, logout are working --- app/controllers/sessions_controller.rb | 28 ++++++++++++++++++++++- app/models/user.rb | 9 +++++++- app/views/sessions/authenticated.jbuilder | 2 ++ app/views/sessions/create.jbuilder | 1 + app/views/users/create.jbuilder | 3 +++ config/routes.rb | 6 +++-- 6 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 app/views/sessions/authenticated.jbuilder create mode 100644 app/views/sessions/create.jbuilder create mode 100644 app/views/users/create.jbuilder diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 350264be..2ecd336d 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,7 +1,7 @@ class SessionsController < ApplicationController def create @user = User.find_by(username: params[:user][:username]) - if @user and @user.password == params[:user][:password] + if @user and BCrypt::Password.new(@user.password) == params[:user][:password] session = @user.sessions.create cookies.permanent.signed[:twitter_session_token] = { value: session.token, @@ -16,5 +16,31 @@ def create } end end + + def authenticated + token = cookies.permanent.signed[:twitter_session_token] + session = Session.find_by(token: token) + if session + user = session.user + render json: { + authenticated: true, + username: user.username + } + else + render json: { + authenticated: false + } + end + end + + def destroy + token = cookies.permanent.signed[:twitter_session_token] + session = Session.find_by(token: token) + if session and session.destroy + render json: { + success: true + } + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index eb20e277..8c0cff06 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,7 +1,14 @@ class User < ApplicationRecord validates :username, presence: true, length: { minimum: 3, maximum: 64 } validates :email, presence: true, length: { minimum: 5, maximum: 500 } - validates :password, presence: true, length: { minimum: 8, maximum: 64 } + validates :password, presence: true, length: { minimum: 8, maximum: 64 } + + after_validation :hash_password + + private + def hash_password + self.password = BCrypt::Password.create(self.password) + end validates_uniqueness_of :username validates_uniqueness_of :email diff --git a/app/views/sessions/authenticated.jbuilder b/app/views/sessions/authenticated.jbuilder new file mode 100644 index 00000000..f6638459 --- /dev/null +++ b/app/views/sessions/authenticated.jbuilder @@ -0,0 +1,2 @@ +json.authenticated true +json.username @user.username diff --git a/app/views/sessions/create.jbuilder b/app/views/sessions/create.jbuilder new file mode 100644 index 00000000..a1f56584 --- /dev/null +++ b/app/views/sessions/create.jbuilder @@ -0,0 +1 @@ +json.success true diff --git a/app/views/users/create.jbuilder b/app/views/users/create.jbuilder new file mode 100644 index 00000000..c7344393 --- /dev/null +++ b/app/views/users/create.jbuilder @@ -0,0 +1,3 @@ +json.user do + json.username @user.username +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 51e96f20..2e605403 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,11 +3,13 @@ get '/feeds' => 'feeds#index' # USERS - post '/users' => 'users#create' - # SESSIONS + # SESSIONS + get '/authenticated' => 'sessions#authenticated' post '/sessions' => 'sessions#create' + delete '/sessions' => 'sessions#destroy' + # TWEETS From db894c70a70f0a52efd44cead74c119149442d8e Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 17:17:20 +0100 Subject: [PATCH 4/7] Tweets post created --- app/controllers/tweets_controller.rb | 24 +++++++++++++++++++++++- app/views/tweets/create.jbuilder | 4 ++++ config/routes.rb | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 app/views/tweets/create.jbuilder diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index b5bda8cc..9ecd54d8 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -1,3 +1,25 @@ class TweetsController < ApplicationController - + def create + token = cookies.signed[:twitter_session_token] + session = Session.find_by(token: token) + + if session + user = session.user + @tweet = user.tweets.new(tweet_params) + + if @tweet.save + render 'tweets/create' # can be omitted + else + render json: { success: false } + end + else + render json: { success: false } + end + end + + private + + def tweet_params + params.require(:tweet).permit(:user, :message) + end end diff --git a/app/views/tweets/create.jbuilder b/app/views/tweets/create.jbuilder new file mode 100644 index 00000000..8ee6b7a3 --- /dev/null +++ b/app/views/tweets/create.jbuilder @@ -0,0 +1,4 @@ +json.tweet do + json.username @tweet.user.username + json.message @tweet.message +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 2e605403..9700d3d9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,7 +11,7 @@ delete '/sessions' => 'sessions#destroy' # TWEETS - + post '/tweets' => 'tweets#create' # Redirect all other paths to index page, which will be taken over by AngularJS get '*path' => 'homepage#index' From 023248565c32f0b3d9ae2b9d4b6229d53d1f95cd Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 18:31:02 +0100 Subject: [PATCH 5/7] delete/:id created --- app/controllers/tweets_controller.rb | 24 ++++++++++++++++++++++++ app/views/tweets/index.jbuilder | 7 +++++++ config/routes.rb | 5 ++++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 app/views/tweets/index.jbuilder diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index 9ecd54d8..b4ae4393 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -1,4 +1,10 @@ class TweetsController < ApplicationController + def index + @tweets = Tweet.all + render 'tweets/index' # can be omitted + end + + def create token = cookies.signed[:twitter_session_token] session = Session.find_by(token: token) @@ -17,6 +23,24 @@ def create end end + def destroy + token = cookies.signed[:twitter_session_token] + session = Session.find_by(token: token) + + if session + user = session.user + @tweet = user.tweets.find_by(id: params[:id]) + + if @tweet and @tweet.destroy + render json: { success: true } + else + render json: { success: false } + end + else + render json: { success: false } + end + end + private def tweet_params diff --git a/app/views/tweets/index.jbuilder b/app/views/tweets/index.jbuilder new file mode 100644 index 00000000..f0242e5c --- /dev/null +++ b/app/views/tweets/index.jbuilder @@ -0,0 +1,7 @@ +json.tweets do + json.array! @tweets do |tweet| + json.id tweet.id + json.username tweet.user.username + json.message tweet.message + end +end diff --git a/config/routes.rb b/config/routes.rb index 9700d3d9..b3ad0d49 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,7 +11,10 @@ delete '/sessions' => 'sessions#destroy' # TWEETS - post '/tweets' => 'tweets#create' + get '/tweets' => 'tweets#index' + #get '/users/:username/tweets' => 'tweets#index_by_user' + post '/tweets' => 'tweets#create' + delete '/tweets/:id' => 'tweets#destroy' # Redirect all other paths to index page, which will be taken over by AngularJS get '*path' => 'homepage#index' From a54663469cae2cdf9f8bb5ed4fd275bd0928fbd8 Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 19:01:01 +0100 Subject: [PATCH 6/7] one rspec failing --- app/controllers/tweets_controller.rb | 9 +++++++++ config/routes.rb | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index b4ae4393..548ac4f6 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -4,6 +4,15 @@ def index render 'tweets/index' # can be omitted end + def index_by_user + user = User.find_by(username: params[:username]) + @tweets = Tweet.where(user_id: user.id) + if @tweets + render 'tweets/index' # can be omitted + else + render json: { tweets: [] } + end + end def create token = cookies.signed[:twitter_session_token] diff --git a/config/routes.rb b/config/routes.rb index b3ad0d49..cd2e7e99 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,7 +12,7 @@ # TWEETS get '/tweets' => 'tweets#index' - #get '/users/:username/tweets' => 'tweets#index_by_user' + get '/users/:username/tweets' => 'tweets#index_by_user' post '/tweets' => 'tweets#create' delete '/tweets/:id' => 'tweets#destroy' From f103dbbce917b1054287ae4f53dc2882cfe9ee80 Mon Sep 17 00:00:00 2001 From: jg93pt Date: Wed, 18 May 2022 19:47:27 +0100 Subject: [PATCH 7/7] solved last failure GET /tweets by adding order by id DESC in the index method --- app/controllers/tweets_controller.rb | 2 +- app/models/tweet.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index 548ac4f6..ce48b281 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -1,6 +1,6 @@ class TweetsController < ApplicationController def index - @tweets = Tweet.all + @tweets = Tweet.all.order("id DESC") render 'tweets/index' # can be omitted end diff --git a/app/models/tweet.rb b/app/models/tweet.rb index 0b6efed3..3867068e 100644 --- a/app/models/tweet.rb +++ b/app/models/tweet.rb @@ -1,5 +1,4 @@ class Tweet < ApplicationRecord belongs_to :user, required:true - validates :message, length: { maximum: 140 }, presence: true end