Skip to content

Commit

Permalink
fix: clear user test data
Browse files Browse the repository at this point in the history
  • Loading branch information
deepakrkris committed Apr 15, 2020
1 parent 2ec12dc commit 02cf3b4
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 43 deletions.
20 changes: 6 additions & 14 deletions examples/passport-login/data/db.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
{
"ids": {
"User": 3,
"UserIdentity": 1005,
"UserCredentials": 2
"User": 8,
"UserIdentity": 1009,
"UserCredentials": 4
},
"models": {
"User": {
"1": "{\"name\":\"Test User\",\"username\":\"[email protected]\",\"email\":\"[email protected]\",\"id\":1}",
"2": "{\"name\":\"\\\"tinkerbell\\\"\",\"username\":\"[email protected]\",\"email\":\"[email protected]\",\"id\":2}"
},
"UserIdentity": {
"1001": "{\"id\":\"1001\",\"provider\":\"custom-oauth2\",\"profile\":{\"emails\":[{\"value\":\"[email protected]\"}]},\"authScheme\":\"custom-oauth2\",\"created\":\"2020-04-14T18:55:47.991Z\",\"userId\":2}",
"1003": "{\"id\":\"1003\",\"provider\":\"custom-oauth2\",\"profile\":{\"emails\":[{\"value\":\"[email protected]\"}]},\"authScheme\":\"custom-oauth2\",\"created\":\"2020-04-14T18:55:47.412Z\",\"userId\":1}"
},
"UserCredentials": {
"[email protected]": "{\"id\":\"[email protected]\",\"password\":\"password\",\"userId\":1}"
}
"User": {},
"UserIdentity": {},
"UserCredentials": {}
}
}
61 changes: 39 additions & 22 deletions examples/passport-login/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/passport-login/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@types/passport-facebook": "^2.1.9",
"@types/passport-google-oauth": "^1.0.41",
"@types/passport-google-oauth2": "^0.1.3",
"@types/passport-http": "^0.3.8",
"@types/passport-local": "^1.0.33",
"@types/passport-oauth2": "^1.4.9",
"body-parser": "^1.19.0",
Expand All @@ -63,6 +64,7 @@
"passport-facebook": "^3.0.0",
"passport-google": "^0.3.0",
"passport-google-oauth2": "^0.2.0",
"passport-http": "^0.3.0",
"passport-local": "^1.0.0",
"passport-oauth2": "^1.5.0",
"tslib": "^1.11.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ describe('example-passport-login acceptance test', () => {
client = supertest('http://127.0.0.1:3000');
});

before(async function clearTestData() {
await supertest('')
.delete('http://localhost:3000/api/clear')
.auth('admin', 'password', {type: 'basic'});
});

after(async function clearTestData() {
await supertest('')
.delete('http://localhost:3000/api/clear')
.auth('admin', 'password', {type: 'basic'});
});

after(async function closeApplication() {
await server.stop();
});
Expand All @@ -63,7 +75,7 @@ describe('example-passport-login acceptance test', () => {
* Test case 2: login as the new user with email id
* Test case 3: logout
*/
context('Scenario 1. Signing up as a NEW user', () => {
context('Scenario 1: Signing up as a NEW user', () => {
/**
* create a local account in the loopback app with the following profile
* username: [email protected]
Expand Down
2 changes: 2 additions & 0 deletions examples/passport-login/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Oauth2AuthStrategy,
LocalAuthStrategy,
SessionStrategy,
BasicStrategy,
} from './authentication-strategies';
import {PassportUserIdentityService, UserServiceBindings} from './services';
import {ApplicationConfig, createBindingFromClass} from '@loopback/core';
Expand Down Expand Up @@ -55,5 +56,6 @@ export class OAuth2LoginApplication extends BootMixin(
this.add(createBindingFromClass(GoogleOauth2Authorization));
this.add(createBindingFromClass(Oauth2AuthStrategy));
this.add(createBindingFromClass(SessionStrategy));
this.add(createBindingFromClass(BasicStrategy));
}
}
129 changes: 129 additions & 0 deletions examples/passport-login/src/authentication-strategies/basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright IBM Corp. 2020. All Rights Reserved.
// Node module: @loopback/example-passport-login
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {AuthenticationStrategy, asAuthStrategy} from '@loopback/authentication';
import {StrategyAdapter} from '@loopback/authentication-passport';
import {Request, RedirectRoute} from '@loopback/rest';
import {UserProfile, securityId} from '@loopback/security';
import {User} from '../models';
import {bind} from '@loopback/context';
import {BasicStrategy as Strategy} from 'passport-http';
import {repository} from '@loopback/repository';
import {UserRepository} from '../repositories';

/**
* basic passport strategy
*/
@bind(asAuthStrategy)
export class BasicStrategy implements AuthenticationStrategy {
name = 'basic';
passportstrategy: Strategy;
strategy: StrategyAdapter<User>;

constructor(
@repository(UserRepository)
public userRepository: UserRepository,
) {
/**
* create a basic passport strategy with verify function to validate credentials
*/
this.passportstrategy = new Strategy(this.verify.bind(this));
/**
* wrap the passport strategy instance with an adapter to plugin to LoopBack authentication
*/
this.strategy = new StrategyAdapter(
this.passportstrategy,
this.name,
this.mapProfile.bind(this),
);
}

/**
* authenticate a request
* @param request
*/
async authenticate(request: Request): Promise<UserProfile | RedirectRoute> {
return this.strategy.authenticate(request);
}

/**
* authenticate user with provided username and password
*
* @param username
* @param password
* @param done
*
* @returns User model
*/
verify(
username: string,
password: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
done: (error: any, user?: any) => void,
): void {
/**
* A dummy admin user is required for ease of testing purposes.
* TODO:
* enable roles and authorization, add user with admin roles in the
* beginning of the tests
*/
if (username === 'admin' && password === 'password') {
return done(null, {
id: 999,
name: 'admin',
username: 'admin',
email: '[email protected]',
});
}

this.userRepository
.find({
where: {
email: username,
},
include: [
{
relation: 'profiles',
},
{
relation: 'credentials',
},
],
})
.then((users: User[]) => {
if (!users || !users.length) {
return done(null, false);
}
const user = users[0];
if (!user.credentials || user.credentials.password !== password) {
return done(null, false);
}
// Authentication passed, return user profile
done(null, user);
})
.catch(err => {
/**
* Error occurred in authenticating process.
* Does not necessarily mean an unauthorized user.
*/
done(err);
});
}

/**
* maps returned User model from verify function to UserProfile
*
* @param user
*/
mapProfile(user: User): UserProfile {
const userProfile: UserProfile = {
[securityId]: '' + user.id,
profile: {
...user,
},
};
return userProfile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './google';
export * from './local';
export * from './types';
export * from './session';
export * from './basic';
15 changes: 15 additions & 0 deletions examples/passport-login/src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import {inject} from '@loopback/context';
import {
post,
del,
requestBody,
Response,
RestBindings,
Expand All @@ -16,6 +17,7 @@ import {repository} from '@loopback/repository';
import {SecurityBindings, UserProfile} from '@loopback/security';
import {authenticate} from '@loopback/authentication';
import {UserCredentialsRepository} from '../repositories/user-credentials.repository';
import {UserIdentityRepository} from '../repositories/user-identity.repository';

export type Credentials = {
email: string;
Expand Down Expand Up @@ -44,6 +46,8 @@ export class UserLoginController {
public userRepository: UserRepository,
@repository(UserCredentialsRepository)
public userCredentialsRepository: UserCredentialsRepository,
@repository(UserIdentityRepository)
public userIdentityRepository: UserIdentityRepository,
) {}

@post('/signup')
Expand Down Expand Up @@ -115,4 +119,15 @@ export class UserLoginController {
response.redirect('/auth/account');
return response;
}

/**
* TODO: enable roles and authorization, add admin role authorization to this endpoint
*/
@authenticate('basic')
@del('/clear')
async clear() {
await this.userCredentialsRepository.deleteAll();
await this.userIdentityRepository.deleteAll();
await this.userRepository.deleteAll();
}
}
Loading

0 comments on commit 02cf3b4

Please sign in to comment.