travis-web/assets/scripts/app/auth.coffee

112 lines
3.8 KiB
CoffeeScript

@Travis.Auth = Ember.Object.extend
state: "signed-out"
receivingEnd: "#{location.protocol}//#{location.host}"
init: ->
window.addEventListener('message', (e) => @receiveMessage(e))
signOut: ->
Travis.storage.removeItem('travis.locale')
Travis.storage.removeItem('travis.user')
Travis.storage.removeItem('travis.token')
Travis.sessionStorage.clear()
Travis.setLocale Travis.default_locale
@set('state', 'signed-out')
@set('user', undefined)
if user = Travis.__container__.lookup('controller:currentUser').get('content')
user.unload()
Travis.__container__.lookup('controller:currentUser').set('content', null)
if router = Travis.__container__.lookup('router:main')
try
router.send('afterSignOut')
catch e
throw e unless e.message =~ /There are no active handlers/
signIn: (data) ->
if data
@autoSignIn(data)
else
@set('state', 'signing-in')
url = "#{@endpoint}/auth/post_message?origin=#{@receivingEnd}"
$('<iframe id="auth-frame" />').hide().appendTo('body').attr('src', url)
autoSignIn: (data) ->
data ||= @userDataFrom(Travis.sessionStorage) || @userDataFrom(Travis.storage)
@setData(data) if data
userDataFrom: (storage) ->
userJSON = storage.getItem('travis.user')
user = JSON.parse userJSON if userJSON?
user = user.user if user?.user
token = storage.getItem('travis.token')
if user && token && @validateUser(user)
{ user: user, token: token }
else
# console.log('dropping user, no token') if token?
storage.removeItem('travis.user')
storage.removeItem('travis.token')
null
validateUser: (user) ->
@validateHas('id', user) && @validateHas('login', user) && @validateHas('token', user) && @validateHas('correct_scopes', user) && user.correct_scopes
validateHas: (field, user) ->
if user[field]
true
else
# console.log("discarding user data, lacks #{field}")
false
setData: (data) ->
@storeData(data, Travis.sessionStorage)
@storeData(data, Travis.storage) unless @userDataFrom(Travis.storage)
user = @loadUser(data.user)
# TODO: we should not use __container__ directly, how to do it better?
# A good answer seems to do auth in context of controller.
Travis.__container__.lookup('controller:currentUser').set('content', user)
@set('state', 'signed-in')
Travis.setLocale(data.user.locale || Travis.default_locale)
Travis.trigger('user:signed_in', data.user)
if router = Travis.__container__.lookup('router:main')
Ember.run.next =>
try
router.send('afterSignIn')
catch e
throw e unless e =~ /There are no active handlers/
@refreshUserData(data.user)
refreshUserData: (user) ->
Travis.ajax.get "/users/#{user.id}", (data) =>
Travis.loadOrMerge(Travis.User, data.user)
# if user is still signed in, update saved data
if @signedIn()
data.user.token = user.token
@storeData(data, Travis.sessionStorage)
@storeData(data, Travis.storage)
signedIn: ->
@get('state') == 'signed-in'
storeData: (data, storage) ->
storage.setItem('travis.token', data.token) if data.token
storage.setItem('travis.user', JSON.stringify(data.user))
loadUser: (user) ->
Travis.loadOrMerge(Travis.User, user)
user = Travis.User.find(user.id)
user.get('permissions')
user
receiveMessage: (event) ->
if event.origin == @expectedOrigin()
if event.data == 'redirect'
window.location = "#{@endpoint}/auth/handshake?redirect_uri=#{location}"
else if event.data.user?
event.data.user.token = event.data.travis_token if event.data.travis_token
@setData(event.data)
expectedOrigin: ->
if @endpoint[0] == '/' then @receivingEnd else @endpoint