diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b0435f5a..2ecd336d 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,3 +1,46 @@ class SessionsController < ApplicationController + def create + @user = User.find_by(username: params[:user][:username]) + if @user and BCrypt::Password.new(@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 + 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/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index 1c4bc871..ce48b281 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -1,3 +1,58 @@ class TweetsController < ApplicationController + def index + @tweets = Tweet.all.order("id DESC") + 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] + 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 + + 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 + params.require(:tweet).permit(:user, :message) + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3f7e4615..e801f179 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,3 +1,22 @@ class UsersController < ApplicationController + def create + @user = User.new(user_params) + if @user.save + render json: { + user: { + username: @user.username, + email: @user.email, + } + } + 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..f9df615e 100644 --- a/app/models/session.rb +++ b/app/models/session.rb @@ -1,3 +1,9 @@ class Session < ApplicationRecord + belongs_to :user, required:true + before_validation :generate_session_token + private + def generate_session_token + self.token = SecureRandom.urlsafe_base64 + end end diff --git a/app/models/tweet.rb b/app/models/tweet.rb index 68958ab1..3867068e 100644 --- a/app/models/tweet.rb +++ b/app/models/tweet.rb @@ -1,3 +1,4 @@ class Tweet < ApplicationRecord - + belongs_to :user, required:true + validates :message, length: { maximum: 140 }, presence: true end diff --git a/app/models/user.rb b/app/models/user.rb index a02d9a68..8c0cff06 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,18 @@ 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 } + + after_validation :hash_password + + private + def hash_password + self.password = BCrypt::Password.create(self.password) + end + validates_uniqueness_of :username + validates_uniqueness_of :email + + has_many :sessions + has_many :tweets end 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/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/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/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 4405fd14..cd2e7e99 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,13 +3,18 @@ get '/feeds' => 'feeds#index' # USERS - + post '/users' => 'users#create' # SESSIONS - + get '/authenticated' => 'sessions#authenticated' + post '/sessions' => 'sessions#create' + delete '/sessions' => 'sessions#destroy' # TWEETS - + 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' 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/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 77bcf0fe..84673c3e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,6 +10,32 @@ # # 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_144443) 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 "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 + t.string "username" + t.string "email" + t.string "password" + t.datetime "timestamps" + end end