Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Align authentication with the API #832

Merged
merged 1 commit into from
Sep 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/controllers/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Ember from 'ember';
export default Ember.Controller.extend({
currentUser: Ember.inject.service(),
errors: [],
noAccountExistsError: false,
noAccountExistsAccount: null,
actions: {
authenticate: function() {
let credentials = this.getProperties('identification', 'password');
Expand All @@ -14,7 +16,10 @@ export default Ember.Controller.extend({
let obj = $.parseJSON(js);
this.get('currentUser').set('currentUserId', obj.user_id);
}, response => {
this.set('errors', response.errors);
let mappedErrors = response.errors.map(str => {
return 'auth.' + str;
});
this.set('errors', mappedErrors);
});
}
}
Expand Down
4 changes: 4 additions & 0 deletions app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ export default {
'login': 'Login',
'logout': 'Logout',
'confirmLogout': 'You have successfully logged out of Ilios. To help protect your account and the security of others, please close all browser windows.',
'missingUsername': 'Username required',
'missingPassword': 'Password required',
'badCredentials': 'Incorrect username or password',
'noAccountExists': 'Your account {{accountName}} does not match any user records in Ilios. If you need further assistance, please contact your school’s Ilios administrator.',
},
'language': {
'select': {
Expand Down
4 changes: 4 additions & 0 deletions app/locales/es/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ export default {
'login': 'Inicio',
'logout': 'Cerrar aplicación',
'confirmLogout': 'Usted ha cerrado la aplicación Ilios con éxito. Para asistir con la protección de su cuenta y la seguridad de otros, favor de cerrar todas las ventanas del navegador.',
'missingUsername': 'Nombre de usaurio requirido',
'missingPassword': 'Contraseña requirida',
'badCredentials': 'Incorrecta contraseña o nombre de usuario',
'noAccountExists': 'Su cuenta no coincide con los registros de Ilios. Si usted necesita más asistencia, póngase en contacto con su administrador de Ilios',
},
'language': {
'select': {
Expand Down
4 changes: 4 additions & 0 deletions app/locales/fr/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ export default {
'login': "Login",
'logout': "Déconnexion",
'confirmLogout': "Vous avez réussi accomplir une fermeture de session en Ilios. Afin de nous aider à protéger votre compte et de la securité des autres, s'il vous plait fermer toutes les fenêtres du navigateur.",
'missingUsername': "Nécessite un nom d'utilisateur",
'missingPassword': "Nécessite un mot de passe",
'badCredentials': "Nom d'utilisateur ou mot de passe incorrect",
'noAccountExists': "Votre compte d'utilisateur {{accountName}} ne correspond pas à ceux des utilisateur enregistre en Ilios. Si vous avez besoin d'aide, n'hesitez pas à communiquer avec votre administrateur d'Ilios.",
},
'language': {
'select': {
Expand Down
6 changes: 3 additions & 3 deletions app/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,10 @@ export default function() {
let errors = [];
var attrs = JSON.parse(request.requestBody);
if(!('username' in attrs) || !attrs.username){
errors.push('Username required');
errors.push('missingUsername');
}
if(!('password' in attrs) || !attrs.password){
errors.push('Password required');
errors.push('missingPassword');
}
let username = attrs.username.toLowerCase();
if(errors.length === 0){
Expand All @@ -306,7 +306,7 @@ export default function() {
jwt: encodedData
};
} else {
errors.push('Incorrect username or password');
errors.push('badCredentials');
}
}
return new Mirage.Response(400, {}, {errors: errors});
Expand Down
42 changes: 31 additions & 11 deletions app/routes/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,58 @@ import ajax from 'ic-ajax';

export default Ember.Route.extend(UnauthenticatedRouteMixin, {
currentUser: Ember.inject.service(),
noAccountExistsError: false,
noAccountExistsAccount: null,
beforeModel(transition){
this._super(transition);
let deferred = Ember.RSVP.defer();

return this.attemptSSOAuth();
},
attemptSSOAuth(){
let defer = Ember.RSVP.defer();
var configUrl = '/auth/config';
var tokenUrl = '/auth/token';
var loginUrl = '/auth/login';
ajax(configUrl).then(data => {
let config = data.config;
if(config.type === 'form' || config.type === 'ldap'){
defer.resolve();
return;
}

if(config.type === 'shibboleth'){
ajax(tokenUrl).then(token => {
if(!token.jwt){
ajax(loginUrl).then(response => {
if(response.status === 'redirect'){
let shibbolethLoginUrl = config.loginUrl;
if(EmberConfig.redirectAfterShibLogin){
let attemptedRoute = encodeURIComponent(window.location.href);
shibbolethLoginUrl += '?target=' + attemptedRoute;
}
window.location.replace(shibbolethLoginUrl);
} else {
}
if(response.status === 'noAccountExists'){
this.set('noAccountExistsError', true);
this.set('noAccountExistsAccount', response.eppn);
defer.resolve();
return;
}
if(response.status === 'success'){
let authenticator = 'authenticator:ilios-jwt';

this.get('session').authenticate(authenticator, {jwt: token.jwt}).then(() => {
this.get('session').authenticate(authenticator, {jwt: response.jwt}).then(() => {
let jwt = this.get('session').get('secure.jwt');
let js = atob(jwt.split('.')[1]);
let obj = $.parseJSON(js);
this.get('currentUser').set('currentUserId', obj.user_id);
});
}
});
} else {
deferred.resolve();
}
});

return deferred.promise;
}
return defer.promise;
},
setupController: function(controller){
controller.set('noAccountExistsError', this.get('noAccountExistsError'));
controller.set('noAccountExistsAccount', this.get('noAccountExistsAccount'));
},
});
52 changes: 28 additions & 24 deletions app/templates/login.hbs
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
<div class='login-form'>
<h2>{{t 'auth.login'}}</h2>
{{#each errors as |error|}}
<div class='error'>{{error}}</div>
{{/each}}
<form {{action 'authenticate' on='submit'}}>
<div class='form-container'>
<div class="detail-content">
<label class="form-col form-col-6 multi-row">
<div class="form-label">{{t 'auth.username'}}:</div>
<div class="form-data">
{{input value=identification}}
</div>
</label>
<br />
<label class="form-col form-col-6 multi-row">
<div class="form-label">{{t 'auth.password'}}:</div>
<div class="form-data">
{{input type='password' value=password}}
</div>
</label>
{{#unless noAccountExistsError}}
<h2>{{t 'auth.login'}}</h2>
{{#each errors as |errorKey|}}
<div class='error'>{{t errorKey}}</div>
{{/each}}
<form {{action 'authenticate' on='submit'}}>
<div class='form-container'>
<div class="detail-content">
<label class="form-col form-col-6 multi-row">
<div class="form-label">{{t 'auth.username'}}:</div>
<div class="form-data">
{{input value=identification}}
</div>
</label>
<br />
<label class="form-col form-col-6 multi-row">
<div class="form-label">{{t 'auth.password'}}:</div>
<div class="form-data">
{{input type='password' value=password}}
</div>
</label>

<div class="form-col-6 form-data-submit">
<button type='submit' class='done text'>{{t 'auth.login'}}</button>
<div class="form-col-6 form-data-submit">
<button type='submit' class='done text'>{{t 'auth.login'}}</button>
</div>
</div>
</div>
</div>
</form>
</form>
{{else}}
<div class='error'>{{t 'auth.noAccountExists' accountName=noAccountExistsAccount}}</div>
{{/unless}}
</div>