Merge pull request #2231 from overleaf/jel-institution-sso-link-error

Add SSO error handling for when identifier linked

GitOrigin-RevId: e2bfa4dba896767d985476ecb78fcee86512a381
This commit is contained in:
Jessica Lawshe
2019-10-15 10:53:10 -05:00
committed by sharelatex
parent 2603597150
commit e27577bd5b
2 changed files with 63 additions and 21 deletions

View File

@@ -17,7 +17,18 @@ async function _addIdentifier(
// before adding the identifier for the email
const user = await UserGetter.promises.getUserByAnyEmail(institutionEmail)
if (user && user._id.toString() !== userId.toString()) {
throw new Errors.EmailExistsError()
const existingEmailData = user.emails.find(
emailData => emailData.email === institutionEmail
)
if (existingEmailData && existingEmailData.samlProviderId) {
// email exists and institution link.
// Return back to requesting page with error
throw new Errors.SAMLIdentityExistsError()
} else {
// Only email exists but not linked, so redirect to linking page
// which will tell this user to log out to link
throw new Errors.EmailExistsError()
}
}
providerId = providerId.toString()
hasEntitlement = !!hasEntitlement

View File

@@ -13,17 +13,22 @@ describe('SAMLIdentityManager', function() {
SAMLUserNotFoundError: sinon.stub()
}
this.user = {
_id: 'user-id',
email: 'dev@overleaf.com',
emails: [
{ email: 'dev@overleaf.com' },
{ email: 'team@overleaf.com', samlProviderId: '1' }
],
samlIdentifiers: [{ providerId: '1' }]
_id: 'user-id-1',
email: 'not-linked@overleaf.com',
emails: [{ email: 'not-linked@overleaf.com' }],
samlIdentifiers: []
}
this.userWithoutInstitutionEmail = {
_id: 'user-id',
emails: [{ email: 'dev@overleaf.com' }]
this.userAlreadyLinked = {
_id: 'user-id-2',
email: 'linked@overleaf.com',
emails: [{ email: 'linked@overleaf.com', samlProviderId: '1' }],
samlIdentifiers: [{ externalUserId: 'linked-id', providerId: '1' }]
}
this.userEmailExists = {
_id: 'user-id-3',
email: 'exists@overleaf.com',
emails: [{ email: 'exists@overleaf.com' }],
samlIdentifiers: []
}
this.institution = {
name: 'Overleaf University'
@@ -37,7 +42,9 @@ describe('SAMLIdentityManager', function() {
'../../models/User': {
User: (this.User = {
findOneAndUpdate: sinon.stub(),
findOne: sinon.stub(this.user),
findOne: sinon.stub().returns({
exec: sinon.stub().resolves()
}),
update: sinon.stub().returns({
exec: sinon.stub().resolves()
})
@@ -81,24 +88,48 @@ describe('SAMLIdentityManager', function() {
})
describe('when email is already associated with another Overleaf account', function() {
beforeEach(function() {
this.UserGetter.promises.getUserByAnyEmail.resolves({
user_id: 'user-id-2'
})
this.UserGetter.promises.getUserByAnyEmail.resolves(
this.userEmailExists
)
})
it('should throw an error if email is associated with another account', async function() {
it('should throw an EmailExistsError error', async function() {
let error
try {
await this.SAMLIdentityManager.linkAccounts(
'user-id-1',
'2',
'overleaf',
true,
'test@overleaf.com'
'not-linked-id',
'exists@overleaf.com',
'provider-id',
true
)
} catch (e) {
error = e
} finally {
expect(error).to.exist
expect(error).to.be.instanceof(this.Errors.EmailExistsError)
expect(this.User.findOneAndUpdate).to.not.have.been.called
}
})
})
describe('when institution identifier is already associated with another Overleaf account', function() {
beforeEach(function() {
this.UserGetter.promises.getUserByAnyEmail.resolves(
this.userAlreadyLinked
)
})
it('should throw an SAMLIdentityExistsError error', async function() {
let error
try {
await this.SAMLIdentityManager.linkAccounts(
'user-id-1',
'already-linked-id',
'linked@overleaf.com',
'provider-id',
true
)
} catch (e) {
error = e
} finally {
expect(error).to.be.instanceof(this.Errors.SAMLIdentityExistsError)
expect(this.User.findOneAndUpdate).to.not.have.been.called
}
})