Skip to content

Instantly share code, notes, and snippets.

@bj-mcduck
Last active August 29, 2015 13:57
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bj-mcduck/9916095 to your computer and use it in GitHub Desktop.
Save bj-mcduck/9916095 to your computer and use it in GitHub Desktop.
Hacky Ember Oauth, check out the repo https://github.com/brandonjmckay/ember-rails-oauth-example
# app/assets/javascripts/ember-app/templates/partials/_header.js.coffee
%nav.navbar.navbar-default.navbar-fixed-top
.container
.navbar-header
%btn.navbar-toggle{ data: { target: '.navbar-collapse', toggle: 'collapse' }, type: 'button' }
%span.sr-only Toggle Navigation
%span.icon-bar
%span.icon-bar
%span.icon-bar
= hb 'link-to "index" class="navbar-brand"' do
Mystics Managed
.collapse.navbar-collapse
%ul.nav.navbar-nav
%li
= hb 'link-to "dream_symbols"' do
Dream Symbols
%li
= hb 'link-to "users"' do
Users
%ul.nav.navbar-nav.navbar-right
= hb 'if userSignedIn' do
%li
%btn-group
%btn.btn.navbar-btn.btn-default.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown' } }
= hb 'signedInUser.screen_name'
%span.caret
%ul.dropdown-menu{ role: 'menu' }
%li
= hb 'link-to "user" signedInUser' do
View Profile
%li
%a{ _action: 'signOut', href: 'sign-out' }
Sign Out
= hb 'else'
%li
= hb 'link-to "sign-in"' do
Sign In
# app/assets/javascripts/ember-app/app.js.coffee
#= require_self
#= require ./store
#= require_tree ./models
#= require_tree ./controllers
#= require_tree ./views
#= require_tree ./helpers
#= require_tree ./components
#= require_tree ./fixtures
#= require_tree ./templates
#= require_tree ./routes
#= require ./router
# app/assets/javascripts/application.js.coffee
#= require bootstrap
#= require handlebars
#= require ember
#= require ember-data
#
#= require_self
#= require ember-app/app
window.App = Ember.Application.create
LOG_TRANSITIONS: true
LOG_TRANSITIONS_INTERNAL: true
LOG_VIEW_LOOKUPS: true
currentUser: localStorage['currentUser']
%header
= hb 'partial "partials/header"'
%main
.container
= hb 'outlet'
# app/assets/javascripts/ember-app/controllers/application_controller.js.coffee
App.ApplicationController = Ember.Controller.extend
signedInUser: (->
@store.find 'user', localStorage['currentUser']
).property('App.currentUser')
userSignedIn: (->
localStorage['currentUser']?
).property('App.currentUser')
actions:
signOut: ->
console.log "Sign Out"
delete localStorage['currentUser']
App.set 'currentUser', `undefined`
# app/models/authentication.rb
class Authentication < ActiveRecord::Base
attr_accessor :omniauth_hash
belongs_to :user
validates :uid, uniqueness: true, presence: true
PROVIDERS = [ :twitter, :google_oauth2, :facebook ]
class << self
def find_by_omniauth(auth)
where( auth.slice(:provider, :uid) ).first
end
def create_from_omniauth(options, user_id)
authentication = Authentication.new
authentication.provider = options[:provider]
authentication.uid = options[:uid]
authentication.user_id = user_id
set_extra_fields( options, authentication )
authentication.save
authentication
end
def set_extra_fields(options, authentication)
case options[:provider]
when 'facebook'
authentication.email = options[:extra][:raw_info][:email]
authentication.gender = options[:extra][:raw_info][:gender]
authentication.image = options[:info][:image]
authentication.full_name = options[:extra][:raw_info][:name]
authentication.screen_name = options[:extra][:raw_info][:username]
when 'google_oauth2'
authentication.email = options[:extra][:raw_info][:email]
authentication.gender = options[:extra][:raw_info][:gender]
authentication.image = options[:extra][:raw_info][:picture]
authentication.full_name = options[:extra][:raw_info][:name]
# Has no username
when 'twitter'
authentication.full_name = options[:extra][:raw_info][:name]
authentication.image = options[:extra][:raw_info][:profile_image_url_https]
authentication.screen_name = options[:extra][:raw_info][:screen_name]
# Has no gender
# Has no email
end
end
end
end
# app/controllers/authentications_controller.rb
class AuthenticationsController < ApplicationController
before_action :set_authentication, only: [:show, :destroy]
before_action :set_user, only: [:create, :destroy]
def show
end
def new
@authentication = Authentication.new
end
def edit
end
def create
@authentication = Authentication.new(authentication_params)
respond_to do |format|
if @authentication.save
format.html { redirect_to @user, notice: 'Authentication was successfully created.' }
format.json { render action: 'show', status: :created, location: @user }
else
format.html { render action: 'new' }
format.json { render json: @authentication.errors, status: :unprocessable_entity }
end
end
end
def destroy
@authentication.destroy
respond_to do |format|
format.html { redirect_to user_url(@user) }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_authentication
@authentication = Authentication.find(params[:id])
end
def set_user
@user = User.find(params[:user_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def authentication_params
params.require(:authentication).permit(:user_id, :provider, :uid, :name, :email)
end
end
# app/views/sessions/create.html.erb
<%= javascript_tag do %>
localStorage['currentUser'] = "<%= @user.id %>";
App.set("currentUser", <%= @user.id %>);
// window.history.pushState( "Redirecting to Root URL", "Title", "/" );
<% end %>
# app/assets/javascripts/ember-app/router.js.coffee
App.Router.reopen
location: 'history'
App.Router.map ->
@resource 'users', path: '/users', ->
@route 'edit', path: 'edit'
@route 'user', path: '/users/:user_id'
@route 'sign-in'
@route 'oauth_callbacks', path: '/auth/:provider/callback'
@route 'missing', path: '*:'
App.OauthCallbacksRoute = Ember.Route.extend
redirect: ->
@transitionTo 'application'
App.MissingRoute = Ember.Route.extend
redirect: ->
@transitionTo 'missing'
# config/routes.rb
App::Application.routes.draw do
get "/auth/:provider/callback", to: "sessions#create"
namespace :api, defaults: { format: 'json' } do
get "/auth/:provider/callback", to: "sessions#create"
resources :authentications
resources :users do
resources :authentications
end
end
root to: 'static_pages#index'
get '*path', to: 'static_pages#index'
end
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
auth = env["omniauth.auth"]
notice = ""
if current_user
@user = current_user
User.add_omniauth_to_user(auth, @user)
notice << "Authentication added successfully."
else
@user = User.from_omniauth( auth )
params[:omni] = env["omniauth.auth"]
session[:user_id] = @user.id
notice << " been signed in!"
end
end
def destroy
session[:user_id] = nil
# session[:omni] = nil
redirect_to root_url, notice: "Signed out!"
end
def failure
redirect_to root_url, alert: "Authentication failed, please try again."
end
end
# app/assets/javascripts/ember-app/store.js.coffee
App.Store = DS.Store.extend()
DS.RESTAdapter.reopen
namespace: 'api'
# app/models/user.rb
class User < ActiveRecord::Base
has_many :authentications
has_one :identity
has_one :profile
has_many :dream_symbols
has_many :interpretations
validates :screen_name, uniqueness: true
accepts_nested_attributes_for :profile
extend FriendlyId
friendly_id :screen_name, use: :slugged
class << self
def add_omniauth_to_user(auth, user)
user.authentications.create_from_omniauth(auth, user.id)
end
def create_from_omniauth(auth)
user = User.create!
profile = Profile.create! user_id: user.id
authentication = user.authentications.create_from_omniauth(auth, user.id)
set_user_fields(user, authentication)
profile.set_fields(
first_name: authentication.first_name,
last_name: authentication.last_name,
full_name: authentication.full_name,
gender: authentication.gender,
image: authentication.image )
user
end
def find_by_identity(auth)
if auth['provider'] == 'identity'
identity = Identity.find_by( screen_name: auth['name'] ) || Identity.find_by( email: auth['email'] )
end
identity.user ? identity.user : nil
end
def find_by_omniauth(auth)
authentication = Authentication.find_by_omniauth(auth)
authentication ? authentication.user : nil
end
def from_omniauth(auth)
find_by_omniauth(auth) || create_from_omniauth(auth)
end
def set_user_fields(user, authentication)
user_gets_updated = user.screen_name.nil? || user.email.nil?
user.screen_name = authentication.screen_name if user.screen_name.nil? && authentication.screen_name
user.email = authentication.email if user.email.nil? && authentication.email
user.save if user_gets_updated
end
end
def should_generate_new_friendly_id?
slug.blank?
end
end
# app/assets/javascripts/ember-app/routes/user_routes.js.coffee
App.UsersRoute = Ember.Route.extend
model: ->
@store.find 'user'
App.UserRoute = Ember.Route.extend
setUpController: (controller, user)->
controller.set('model', user)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment