From f08b5bb7249a72c65d3a438eeea86d2427a6448d Mon Sep 17 00:00:00 2001 From: Ting Wong Date: Tue, 18 Apr 2017 10:48:53 -0700 Subject: [PATCH 1/2] all changes before wave 3 --- .gitignore | 3 + Gemfile | 5 ++ Gemfile.lock | 34 +++++++++++- app/assets/stylesheets/application.scss | 5 ++ app/controllers/application_controller.rb | 19 +++++-- app/controllers/sessions_controller.rb | 55 ++++++++++++++----- app/controllers/works_controller.rb | 5 +- app/models/user.rb | 9 +++ app/views/layouts/application.html.erb | 20 ++++--- app/views/works/show.html.erb | 1 + config/initializers/omniauth.rb | 3 + config/routes.rb | 3 +- ...170417215139_add_columns_to_users_table.rb | 7 +++ db/schema.rb | 9 ++- 14 files changed, 144 insertions(+), 34 deletions(-) create mode 100644 config/initializers/omniauth.rb create mode 100644 db/migrate/20170417215139_add_columns_to_users_table.rb diff --git a/.gitignore b/.gitignore index 48fb168..1a2ff20 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ # Ignore Byebug command history file. .byebug_history + +# Hide .env files +.env diff --git a/Gemfile b/Gemfile index 24756e7..b5c1c92 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,9 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem "omniauth" +gem "omniauth-github" + # Use the Foundation CSS framework gem 'foundation-rails' @@ -48,6 +51,7 @@ group :development, :test do # Use pry for rails console gem 'pry-rails' + gem 'binding_of_caller' end group :test do @@ -64,6 +68,7 @@ group :development do # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' + gem 'dotenv-rails' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Gemfile.lock b/Gemfile.lock index 4d99ffe..72563c8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,6 +49,8 @@ GEM erubis (>= 2.6.6) rack (>= 0.9.0) bindex (0.5.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) builder (3.2.3) byebug (9.0.6) coderay (1.1.1) @@ -60,8 +62,15 @@ GEM execjs coffee-script-source (1.12.2) concurrent-ruby (1.0.5) + debug_inspector (0.0.2) + dotenv (2.2.0) + dotenv-rails (2.2.0) + dotenv (= 2.2.0) + railties (>= 3.2, < 5.1) erubis (2.7.0) execjs (2.7.0) + faraday (0.11.0) + multipart-post (>= 1.2, < 3) ffi (1.9.18) foundation-rails (6.3.0.0) railties (>= 3.1.0) @@ -69,6 +78,7 @@ GEM sprockets-es6 (>= 0.9.0) globalid (0.3.7) activesupport (>= 4.1.0) + hashie (3.5.5) i18n (0.8.1) jbuilder (2.6.3) activesupport (>= 3.0.0, < 5.2) @@ -77,6 +87,7 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) + jwt (1.5.6) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -104,9 +115,26 @@ GEM minitest (~> 5.0) rails (>= 4.1) multi_json (1.12.1) + multi_xml (0.6.0) + multipart-post (2.0.0) nio4r (2.0.0) nokogiri (1.7.1) mini_portile2 (~> 2.1.0) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-github (1.2.3) + omniauth (~> 1.5) + omniauth-oauth2 (>= 1.4.0, < 2.0) + omniauth-oauth2 (1.4.0) + oauth2 (~> 1.0) + omniauth (~> 1.2) pg (0.20.0) pry (0.10.4) coderay (~> 1.1.0) @@ -194,8 +222,10 @@ PLATFORMS DEPENDENCIES better_errors + binding_of_caller byebug coffee-rails (~> 4.2) + dotenv-rails foundation-rails jbuilder (~> 2.5) jquery-rails @@ -204,6 +234,8 @@ DEPENDENCIES minitest-reporters minitest-skip minitest-spec-rails + omniauth + omniauth-github pg (~> 0.18) pry-rails puma (~> 3.0) @@ -220,4 +252,4 @@ RUBY VERSION ruby 2.4.0p0 BUNDLED WITH - 1.14.4 + 1.14.6 diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index a0275f2..38193ea 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -19,6 +19,11 @@ color: slategrey; } + .flash { + color: red; + font-size: 3rem; + } + .page-header { max-width: 100%; background: image-url('owl.jpg'); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 087352a..099e442 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,17 +1,26 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception - before_action :find_user + before_action :lookup_user + def render_404 # DPR: supposedly this will actually render a 404 page in production raise ActionController::RoutingError.new('Not Found') end -private - def find_user - if session[:user_id] - @login_user = User.find_by(id: session[:user_id]) + private + def lookup_user + unless session[:user_id].nil? + @current_user = User.find_by(id: session[:user_id]) + end + end + + def require_login + lookup_user + if @current_user.nil? + flash[:result_text] = "You need to be logged to see that page" + redirect_to root_path end end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5bce99e..62ec5fb 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -2,25 +2,52 @@ class SessionsController < ApplicationController def login_form end + # def login + # username = params[:username] + # if username and user = User.find_by(username: username) + # session[:user_id] = user.id + # flash[:status] = :success + # flash[:result_text] = "Successfully logged in as existing user #{user.username}" + # else + # user = User.new(username: username) + # if user.save + # session[:user_id] = user.id + # flash[:status] = :success + # flash[:result_text] = "Successfully created new user #{user.username} with ID #{user.id}" + # else + # flash.now[:status] = :failure + # flash.now[:result_text] = "Could not log in" + # flash.now[:messages] = user.errors.messages + # render "login_form", status: :bad_request + # return + # end + # end + # redirect_to root_path + # end + # + def login - username = params[:username] - if username and user = User.find_by(username: username) - session[:user_id] = user.id - flash[:status] = :success - flash[:result_text] = "Successfully logged in as existing user #{user.username}" - else - user = User.new(username: username) + auth_hash = request.env['omniauth.auth'] + user = User.from_github(auth_hash) + + #attempt to find these credentials in our DB + user = User.find_by(oauth_provider: params[:provider], oauth_uid: auth_hash["uid"]) + if user.nil? + # Don't know this user, build a new user + user = User.from_github(auth_hash) if user.save session[:user_id] = user.id - flash[:status] = :success - flash[:result_text] = "Successfully created new user #{user.username} with ID #{user.id}" + flash[:result_text] = "Successfully logged in as new user: #{user.username}" else - flash.now[:status] = :failure - flash.now[:result_text] = "Could not log in" - flash.now[:messages] = user.errors.messages - render "login_form", status: :bad_request - return + flash[:result_text] = "Login unsuccessful" + user.errors.messages.each do |field, problem| + flash[:field] = problem.join(', ') + end end + else + #Welcome back! + session[:user_id] = user.id + flash[:result_text] = "Welcome back, #{user.username}" end redirect_to root_path end diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 8ac0bcc..e830b30 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -3,6 +3,7 @@ class WorksController < ApplicationController # of work we're dealing with before_action :category_from_url, only: [:index, :new, :create] before_action :category_from_work, except: [:root, :index, :new, :create] + before_action :require_login, except: [:root] def root @albums = Work.best_albums @@ -35,7 +36,7 @@ def create end def show - @votes = @work.votes.order(created_at: :desc) + flash[:message] = "You need to login to see this" end def edit @@ -89,7 +90,7 @@ def upvote redirect_back fallback_location: works_path(@media_category), status: status end -private + private def media_params params.require(:work).permit(:title, :category, :creator, :description, :publication_year) end diff --git a/app/models/user.rb b/app/models/user.rb index 4cac8fe..cc1ffb9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,4 +3,13 @@ class User < ApplicationRecord has_many :ranked_works, through: :votes, source: :work validates :username, uniqueness: true, presence: true + + def self.from_github(auth_hash) + user = User.new + user.username = auth_hash["info"]["nickname"] + user.email = auth_hash["info"]["email"] + user.oauth_uid = auth_hash["uid"] + user.oauth_provider = "github" + return user + end end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9231526..4dd6335 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -18,16 +18,20 @@
- <% if @login_user %> -

Logged in as <%= link_to @login_user.username, user_path(@login_user) %>

- <%= link_to "Log Out", logout_path, method: :post, class: "button float-right" %> - <% else %> -

Not logged in

- <%= link_to "Log In", login_path, class: "button float-right" %> - <% end %> -
+
+ <% if @current_user %> +

Logged in as <%= link_to @current_user.username, user_path(@current_user) %>

+ <%= link_to "Log Out", logout_path, method: :post, class: "button float-right" %> + <% else %> +

Not logged in

+ <%= link_to "Log In", "/auth/github", class: "button float-right" %> + <% end %> +
+ + + <% if flash[:result_text] or flash[:messages] %>

<%= flash[:status] == :failure ? "A problem occurred: " : "" %><%= flash[:result_text] %>

diff --git a/app/views/works/show.html.erb b/app/views/works/show.html.erb index 85faecc..3157d07 100644 --- a/app/views/works/show.html.erb +++ b/app/views/works/show.html.erb @@ -1,3 +1,4 @@ +

<%= @work.title %>

Created by: <%= @work.creator %>

diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 0000000..fd44161 --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,3 @@ +Rails.application.config.middleware.use OmniAuth::Builder do + provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user:email" +end diff --git a/config/routes.rb b/config/routes.rb index 4352c93..29c47c3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,6 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html root 'works#root' - get '/login', to: 'sessions#login_form', as: 'login' post '/login', to: 'sessions#login' post '/logout', to: 'sessions#logout', as: 'logout' @@ -16,4 +15,6 @@ post '/works/:id/upvote', to: 'works#upvote', as: 'upvote' resources :users, only: [:index, :show] + + get "/auth/:provider/callback", to: "sessions#login" end diff --git a/db/migrate/20170417215139_add_columns_to_users_table.rb b/db/migrate/20170417215139_add_columns_to_users_table.rb new file mode 100644 index 0000000..f6061a0 --- /dev/null +++ b/db/migrate/20170417215139_add_columns_to_users_table.rb @@ -0,0 +1,7 @@ +class AddColumnsToUsersTable < ActiveRecord::Migration[5.0] + def change + add_column :users, :email, :string + add_column :users, :oauth_uid, :string + add_column :users, :oauth_provider, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 6bc8ba5..84156ea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,15 +10,18 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170407164321) do +ActiveRecord::Schema.define(version: 20170417215139) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" create_table "users", force: :cascade do |t| t.string "username" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "email" + t.string "oauth_uid" + t.string "oauth_provider" end create_table "votes", force: :cascade do |t| From 35a4b46527f14e100cc078390099d0ec68b413d5 Mon Sep 17 00:00:00 2001 From: Ting Wong Date: Sun, 30 Apr 2017 20:12:29 -0700 Subject: [PATCH 2/2] instructor media ranker --- Gemfile | 1 + Gemfile.lock | 10 +++++++++ app/controllers/works_controller.rb | 22 ++++++++++++++++++- app/models/user.rb | 1 + app/models/work.rb | 1 + config/initializers/omniauth.rb | 6 +++++ ...20170418174911_setup_work_user_relation.rb | 5 +++++ db/schema.rb | 5 ++++- 8 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170418174911_setup_work_user_relation.rb diff --git a/Gemfile b/Gemfile index b5c1c92..ea155c8 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ gem 'jbuilder', '~> 2.5' gem "omniauth" gem "omniauth-github" +gem "omniauth-google-oauth2", "~> 0.2.1" # Use the Foundation CSS framework gem 'foundation-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 72563c8..57207c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -38,6 +38,8 @@ GEM i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) ansi (1.5.0) arel (7.1.4) babel-source (5.8.35) @@ -132,6 +134,12 @@ GEM omniauth-github (1.2.3) omniauth (~> 1.5) omniauth-oauth2 (>= 1.4.0, < 2.0) + omniauth-google-oauth2 (0.2.8) + addressable (~> 2.3) + jwt (~> 1.0) + multi_json (~> 1.3) + omniauth (>= 1.1.1) + omniauth-oauth2 (>= 1.1.1) omniauth-oauth2 (1.4.0) oauth2 (~> 1.0) omniauth (~> 1.2) @@ -142,6 +150,7 @@ GEM slop (~> 3.4) pry-rails (0.3.4) pry (>= 0.9.10) + public_suffix (2.0.5) puma (3.8.2) rack (2.0.1) rack-test (0.6.3) @@ -236,6 +245,7 @@ DEPENDENCIES minitest-spec-rails omniauth omniauth-github + omniauth-google-oauth2 (~> 0.2.1) pg (~> 0.18) pry-rails puma (~> 3.0) diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index e830b30..6293a33 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -4,6 +4,7 @@ class WorksController < ApplicationController before_action :category_from_url, only: [:index, :new, :create] before_action :category_from_work, except: [:root, :index, :new, :create] before_action :require_login, except: [:root] + before_action :auth_user, only:[:edit, :destroy, :update] def root @albums = Work.best_albums @@ -22,7 +23,16 @@ def new end def create - @work = Work.new(media_params) + work_info = { + title: media_params[:title], + creator: media_params[:creator], + description: media_params[:description], + category: @media_category, + publication_year: media_params[:publication_year], + user_id: @current_user.id + } + + @work = Work.new(work_info) if @work.save flash[:status] = :success flash[:result_text] = "Successfully created #{@media_category.singularize} #{@work.id}" @@ -36,6 +46,7 @@ def create end def show + @votes = @work.votes.order(created_at: :desc) flash[:message] = "You need to login to see this" end @@ -104,4 +115,13 @@ def category_from_work render_404 unless @work @media_category = @work.category.downcase.pluralize end + + def auth_user + lookup_user + unless @current_user.id == Work.find_by(id: params[:id]).user_id + flash[:result_text] = "You are not authorized for this action!" + status = :unauthorized + redirect_to root_path + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index cc1ffb9..91f5b86 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,6 @@ class User < ApplicationRecord has_many :votes + has_many :works has_many :ranked_works, through: :votes, source: :work validates :username, uniqueness: true, presence: true diff --git a/app/models/work.rb b/app/models/work.rb index 7b27fd3..e18a807 100644 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -1,5 +1,6 @@ class Work < ApplicationRecord has_many :votes, dependent: :destroy + belongs_to :user has_many :ranking_users, through: :votes, source: :user validates :category, presence: true, diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index fd44161..e0174c6 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -1,3 +1,9 @@ Rails.application.config.middleware.use OmniAuth::Builder do provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user:email" end + +OmniAuth.config.logger = Rails.logger + +Rails.application.config.middleware.use OmniAuth::Builder do + provider :google_oauth2, 'my Google client id', 'my Google client secret', {client_options: {ssl: {ca_file: Rails.root.join("cacert.pem").to_s}}} +end diff --git a/db/migrate/20170418174911_setup_work_user_relation.rb b/db/migrate/20170418174911_setup_work_user_relation.rb new file mode 100644 index 0000000..ed019af --- /dev/null +++ b/db/migrate/20170418174911_setup_work_user_relation.rb @@ -0,0 +1,5 @@ +class SetupWorkUserRelation < ActiveRecord::Migration[5.0] + def change + add_reference :works, :user, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 84156ea..65db2a8 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: 20170417215139) do +ActiveRecord::Schema.define(version: 20170418174911) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,8 +42,11 @@ t.datetime "updated_at", null: false t.integer "vote_count", default: 0 t.integer "publication_year" + t.integer "user_id" + t.index ["user_id"], name: "index_works_on_user_id", using: :btree end add_foreign_key "votes", "users" add_foreign_key "votes", "works" + add_foreign_key "works", "users" end