diff --git a/Gemfile b/Gemfile index f177aa3..3961c14 100644 --- a/Gemfile +++ b/Gemfile @@ -48,6 +48,8 @@ gem 'will_paginate-bootstrap', '~> 1.0.1' gem 'devise', '~> 4.5.0' gem 'devise-bootstrap-views', '~> 0.0.11' +gem 'omniauth' +gem 'omniauth-github' gem 'codemirror-rails', '~> 5.16.0' # Use ActiveModel has_secure_password diff --git a/Gemfile.lock b/Gemfile.lock index 53dd765..d33a1a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,11 +85,14 @@ GEM docile (1.3.1) erubi (1.8.0) execjs (2.7.0) + faraday (0.15.4) + multipart-post (>= 1.2, < 3) ffi (1.9.25) ffi (1.9.25-x64-mingw32) ffi (1.9.25-x86-mingw32) globalid (0.4.2) activesupport (>= 4.2.0) + hashie (3.6.0) i18n (0.9.5) concurrent-ruby (~> 1.0) jbuilder (2.8.0) @@ -100,6 +103,7 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (1.8.6) + jwt (2.1.0) loofah (2.2.3) crass (~> 1.0.2) nokogiri (>= 1.5.9) @@ -116,6 +120,8 @@ GEM msgpack (1.2.6-x64-mingw32) msgpack (1.2.6-x86-mingw32) multi_json (1.13.1) + multi_xml (0.6.0) + multipart-post (2.0.0) mysql2 (0.5.2) mysql2 (0.5.2-x64-mingw32) mysql2 (0.5.2-x86-mingw32) @@ -126,6 +132,21 @@ GEM mini_portile2 (~> 2.4.0) nokogiri (1.10.1-x86-mingw32) mini_portile2 (~> 2.4.0) + oauth2 (1.4.1) + faraday (>= 0.8, < 0.16.0) + jwt (>= 1.0, < 3.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (>= 1.2, < 3) + omniauth (1.9.0) + hashie (>= 3.4.6, < 3.7.0) + rack (>= 1.6.2, < 3) + omniauth-github (1.3.0) + omniauth (~> 1.5) + omniauth-oauth2 (>= 1.4.0, < 2.0) + omniauth-oauth2 (1.6.0) + oauth2 (~> 1.1) + omniauth (~> 1.9) orm_adapter (0.5.0) rack (2.0.6) rack-test (1.1.0) @@ -240,6 +261,8 @@ DEPENDENCIES jbuilder (~> 2.8.0) jquery-rails (~> 4.3.3) mysql2 (~> 0.5.2) + omniauth + omniauth-github rails (= 5.2.2) rails-controller-testing rails-i18n (~> 5.1.3) diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index f76d697..34852f6 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -1,3 +1,8 @@ class AdminController < ApplicationController - before_action :authenticate_admin! + before_action :authenticate! + + def authenticate! + authenticate_user! + raise SecurityError unless current_user.admin? + end end \ No newline at end of file diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb new file mode 100644 index 0000000..e64d703 --- /dev/null +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -0,0 +1,14 @@ +class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController + skip_before_action :verify_authenticity_token + + def sign_in_with(provider_name) + @user = User.from_omniauth(request.env["omniauth.auth"]) + @user.remember_me! + sign_in_and_redirect @user, event: :authentication + set_flash_message(:notice, :success, kind: provider_name) if is_navigational_format? + end + + def developer + sign_in_with "Developer" + end +end \ No newline at end of file diff --git a/app/models/admin.rb b/app/models/admin.rb deleted file mode 100644 index 1f68418..0000000 --- a/app/models/admin.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Admin < ApplicationRecord - # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, - :recoverable, :rememberable, :trackable, :validatable -end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..803a25c --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,11 @@ +class User < ApplicationRecord + devise :omniauthable, :rememberable + + enum role: [:user, :admin] + + def self.from_omniauth(auth) + where(provider: auth.provider, uid: auth.uid).first_or_create do |user| + user.name = auth.info.name + end + end +end diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 81d5a05..285997e 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -6,16 +6,17 @@ <%= nav class: 'navbar-left' do %> <%= link_to t('application.info'), about_info_path %> <%= link_to Problem.model_name.human(count: 2), problems_path %> - <% if admin_signed_in? %> + <% if user_signed_in? and current_user.admin? %> <%= link_to t('admin.dashboard.index.administration'), admin_dashboard_index_path %> <% end %> <% end %> <%= nav class: 'navbar-right' do %> <%= link_to t('application.legal'), about_legal_path %> - <% if admin_signed_in? %> - <%= link_to(t('application.sign_out'), destroy_admin_session_path, method: :delete) %> + <% if user_signed_in? %> +
  • Eingeloggt als <%= current_user.name %>
  • + <%= link_to(t('application.sign_out'), destroy_user_session_path, method: :delete) %> <% else %> - <%= link_to(t('application.sign_in'), new_admin_session_path) %> + <%= link_to(t('application.sign_in'), user_developer_omniauth_authorize_path) %> <% end %> <% end %> <% end %> diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 567d932..8aa5cf9 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -233,6 +233,7 @@ Devise.setup do |config| # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + config.omniauth :developer, fields: [:name], uid_field: :name # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or diff --git a/config/routes.rb b/config/routes.rb index cb13527..2a444da 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,7 +22,13 @@ Rails.application.routes.draw do resources :translations, only: [:new, :create] end - devise_for :admins, skip: :registrations + devise_for :users, :controllers => { + :omniauth_callbacks => "users/omniauth_callbacks" + } + devise_scope :user do + delete 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session + end + namespace :admin do get '', to: 'dashboard#index', as: 'dashboard_index' post '/update_problem_count', to: 'dashboard#update_problem_count', as: 'dashboard_update_problem_count' diff --git a/db/migrate/20190203145552_devise_create_users.rb b/db/migrate/20190203145552_devise_create_users.rb new file mode 100644 index 0000000..cc66551 --- /dev/null +++ b/db/migrate/20190203145552_devise_create_users.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +class DeviseCreateUsers < ActiveRecord::Migration[5.2] + def change + create_table :users do |t| + ## OmniAuth-able + t.string :provider, null: false + t.string :uid, null: false + + ## User role + t.integer :role, default: 0 + + ## Rememberable + t.datetime :remember_created_at + + + ## Database authenticatable + # t.string :email, null: false, default: "" + # t.string :encrypted_password, null: false, default: "" + + ## Recoverable + # t.string :reset_password_token + # t.datetime :reset_password_sent_at + + + ## Trackable + # t.integer :sign_in_count, default: 0, null: false + # t.datetime :current_sign_in_at + # t.datetime :last_sign_in_at + # t.string :current_sign_in_ip + # t.string :last_sign_in_ip + + ## Confirmable + # t.string :confirmation_token + # t.datetime :confirmed_at + # t.datetime :confirmation_sent_at + # t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + # t.string :unlock_token # Only if unlock strategy is :email or :both + # t.datetime :locked_at + + + t.timestamps null: false + end + + # add_index :users, :email, unique: true + # add_index :users, :reset_password_token, unique: true + # add_index :users, :confirmation_token, unique: true + # add_index :users, :unlock_token, unique: true + end +end diff --git a/db/migrate/20190203150923_add_name_to_users.rb b/db/migrate/20190203150923_add_name_to_users.rb new file mode 100644 index 0000000..af42193 --- /dev/null +++ b/db/migrate/20190203150923_add_name_to_users.rb @@ -0,0 +1,5 @@ +class AddNameToUsers < ActiveRecord::Migration[5.2] + def change + add_column :users, :name, :string + end +end diff --git a/db/migrate/20190203164629_drop_admins.rb b/db/migrate/20190203164629_drop_admins.rb new file mode 100644 index 0000000..f47301e --- /dev/null +++ b/db/migrate/20190203164629_drop_admins.rb @@ -0,0 +1,8 @@ +class DropAdmins < ActiveRecord::Migration[5.2] + def up + drop_table :admins + end + def down + fail ActiveRecord::IrreversibleMigration + end +end diff --git a/db/schema.rb b/db/schema.rb index f50f95e..1d5881a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,24 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_02_02_113250) do - - create_table "admins", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" - t.index ["email"], name: "index_admins_on_email", unique: true - t.index ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true - end +ActiveRecord::Schema.define(version: 2019_02_03_164629) do create_table "problems", force: :cascade do |t| t.datetime "created_at" @@ -46,4 +29,14 @@ ActiveRecord::Schema.define(version: 2019_02_02_113250) do t.index ["problem_id"], name: "index_translations_on_problem_id" end + create_table "users", force: :cascade do |t| + t.string "provider", null: false + t.string "uid", null: false + t.integer "role", default: 0 + t.datetime "remember_created_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + end + end diff --git a/test/controllers/admin/dashboard_controller_test.rb b/test/controllers/admin/dashboard_controller_test.rb index be3e2ed..586211f 100644 --- a/test/controllers/admin/dashboard_controller_test.rb +++ b/test/controllers/admin/dashboard_controller_test.rb @@ -4,7 +4,7 @@ class Admin::DashboardControllerTest < ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers setup do - login + login_admin end test "should get index" do diff --git a/test/controllers/admin/translations_controller_test.rb b/test/controllers/admin/translations_controller_test.rb index 4536ae0..84fac82 100644 --- a/test/controllers/admin/translations_controller_test.rb +++ b/test/controllers/admin/translations_controller_test.rb @@ -4,7 +4,7 @@ class Admin::TranslationsControllerTest < ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers setup do - login + login_admin @translation = translations(:translation_one) @translation_alternative = translations(:translation_two_alternative) end diff --git a/test/fixtures/admins.yml b/test/fixtures/users.yml similarity index 53% rename from test/fixtures/admins.yml rename to test/fixtures/users.yml index 3edd24e..bac0e2d 100644 --- a/test/fixtures/admins.yml +++ b/test/fixtures/users.yml @@ -1,10 +1,17 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -# This model initially had no columns defined. If you add columns to the +# This model initially had no columns defined. If you add columns to the # model remove the '{}' from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # - admin: - email: admin@example.com - encrypted_password: <%= Devise::Encryptor.digest(Admin, 'password') %> \ No newline at end of file + provider: github + uid: admin + name: admin + role: 1 + +translator: + provider: github + uid: translator + name: translator + role: 0 \ No newline at end of file diff --git a/test/models/admin_test.rb b/test/models/user_test.rb similarity index 64% rename from test/models/admin_test.rb rename to test/models/user_test.rb index ab20b8c..82f61e0 100644 --- a/test/models/admin_test.rb +++ b/test/models/user_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class AdminTest < ActiveSupport::TestCase +class UserTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/test_helper.rb b/test/test_helper.rb index 9037e51..234ca2a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,8 +10,13 @@ class ActiveSupport::TestCase fixtures :all # Add more helper methods to be used by all tests here... - def login - admin = admins(:admin) + def login_admin + admin = users(:admin) sign_in admin end + + def login_translator + translator = users(:translator) + sign_in translator + end end