Skip to content

Commit

Permalink
feat(authentication-service): enable tenant aware metrics (#2044)
Browse files Browse the repository at this point in the history
* feat(authentication-service): enable tenant aware metrics

enable tenant aware metrics

GH-1980

* feat(authentication-service): make service for login activity repository functions

GH-1980

* feat(authentication-service): remove user-view related changes
  • Loading branch information
arpit1503khanna authored Apr 4, 2024
1 parent a276aea commit e67280d
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class TenantGuardService<T extends EntityWithTenantId, ID>
throw new HttpErrors.Unauthorized(TenantUtilitiesErrorKeys.TenantIdMissing);
}

private buildWhere(user: UserInToken, where?: Where<T>, id?: ID): Where<T> {
buildWhere(user: UserInToken, where?: Where<T>, id?: ID): Where<T> {
const whereBuilder = new WhereBuilder<AnyObject>();
const extraFilter: AnyObject = {
tenantId: user.tenantId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const User = {
id: 1,
username: 'test_user',
password: 'test_password',
tenantId: 'tenant1',
};
export const testUserPayload = {
...User,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import {HttpErrors} from '@loopback/rest';
import {
StubbedInstanceWithSinonAccessor,
createStubInstance,
expect,
} from '@loopback/testlab';
import {
UserTenantRepository,
UserRepository,
OtpRepository,
AuthClientRepository,
} from '../../../repositories';
import {UserStatus} from '@sourceloop/core';
import sinon from 'sinon';
import {ResourceOwnerVerifyProvider} from '../../../modules/auth/providers/resource-owner-verify.provider';
import {
AuthClient,
Otp,
Expand All @@ -23,8 +18,13 @@ import {
UserTenantWithRelations,
UserWithRelations,
} from '../../../models';
import {UserStatus} from '@sourceloop/core';
import {HttpErrors} from '@loopback/rest';
import {ResourceOwnerVerifyProvider} from '../../../modules/auth/providers/resource-owner-verify.provider';
import {
AuthClientRepository,
OtpRepository,
UserRepository,
UserTenantRepository,
} from '../../../repositories';

describe('Resource Owner Verify Provider', () => {
let userRepo: StubbedInstanceWithSinonAccessor<UserRepository>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import {
UserRepository,
UserTenantRepository,
} from '../../../repositories/sequelize';
import {LoginHelperService, OtpService} from '../../../services';
import {
ActiveUserFilterBuilderService,
LoginActivityHelperService,
LoginHelperService,
OtpService,
} from '../../../services';
import {getBaseClass} from '../../utils/getBaseClass';
import {SequelizeAuthenticationServiceApplication} from './sequelize.application';
let sequelizeApp: SequelizeAuthenticationServiceApplication;
Expand Down Expand Up @@ -56,19 +61,24 @@ describe('Sequelize Component', () => {
const expectedBindings = [
{
controller: LoginActivityController,
repository: LoginActivityRepository,
prop: 'loginActivityRepo',
services: [
LoginActivityHelperService,
ActiveUserFilterBuilderService,
],
props: ['loginActivityHelperService', 'filterBuilder'],
},
];

for (const {controller, repository, prop} of expectedBindings) {
for (const {controller, services, props} of expectedBindings) {
const controllerInstance: ControllerInstance = sequelizeApp.getSync(
sequelizeApp.controller(controller).key,
);
expect(sequelizeApp.controller(controller).source?.value).to.be.oneOf(
boundControllerClasses.map(e => e.source?.value),
);
expect(controllerInstance[prop]).to.be.instanceOf(repository);
for (let i = 0; i < props.length; i++) {
expect(controllerInstance[props[i]]).to.be.instanceOf(services[i]);
}
}
});
it('Uses the sequelize compatible repository in Otpcontroller', async () => {
Expand Down
9 changes: 9 additions & 0 deletions services/authentication-service/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
CoreComponent,
SECURITY_SCHEME_SPEC,
SFCoreBindings,
TenantGuardService,
TenantUtilitiesBindings,
} from '@sourceloop/core';
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
Expand Down Expand Up @@ -114,6 +116,7 @@ import {repositories as sequelizeRepositories} from './repositories/sequelize';
import {MySequence} from './sequence';
import {
ActiveUserFilterBuilderService,
LoginActivityHelperService,
LoginHelperService,
OtpService,
} from './services';
Expand Down Expand Up @@ -183,12 +186,18 @@ export class AuthenticationServiceComponent implements Component {
.bind('services.LoginHelperService')
.toClass(LoginHelperService);
this.application.bind('services.otpService').toClass(OtpService);
this.application
.bind('services.loginActivityHelperService')
.toClass(LoginActivityHelperService);

//set the userActivity to false by default
this.application
.bind(AuthServiceBindings.MarkUserActivity)
.to({markUserActivity: false});
this.models = models;
this.application
.bind(TenantUtilitiesBindings.GuardService)
.toClass(TenantGuardService);
this.application
.bind('services.ActiveUserFilterBuilderService')
.toClass(ActiveUserFilterBuilderService);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import {inject} from '@loopback/core';
import {
Count,
CountSchema,
Filter,
Where,
repository,
} from '@loopback/repository';
import {inject} from '@loopback/context';
import {Count, CountSchema, Filter, Where} from '@loopback/repository';
import {
get,
getFilterSchemaFor,
Expand All @@ -23,15 +17,15 @@ import {authorize} from 'loopback4-authorization';
import moment from 'moment';
import {ActiveUsersRange, PermissionKey} from '../enums';
import {ActiveUsersFilter, LoginActivity} from '../models';
import {LoginActivityRepository} from '../repositories';
import {ActiveUserFilterBuilderService} from '../services';
import {LoginActivityHelperService} from '../services/login-activity-helper.service';
import {ActiveUsersGroupData} from '../types';

const baseUrl = '/login-activity';
export class LoginActivityController {
constructor(
@repository(LoginActivityRepository)
private readonly loginActivityRepo: LoginActivityRepository,
@inject('services.loginActivityHelperService')
private readonly loginActivityHelperService: LoginActivityHelperService,
@inject('services.ActiveUserFilterBuilderService')
private readonly filterBuilder: ActiveUserFilterBuilderService,
) {}
Expand All @@ -55,7 +49,7 @@ export class LoginActivityController {
@param.query.object('where', getWhereSchemaFor(LoginActivity))
where?: Where<LoginActivity>,
): Promise<Count> {
return this.loginActivityRepo.count(where);
return this.loginActivityHelperService.count(where);
}

@authenticate(STRATEGY.BEARER, {
Expand Down Expand Up @@ -84,7 +78,7 @@ export class LoginActivityController {
@param.query.object('filter', getFilterSchemaFor(LoginActivity))
filter?: Filter<LoginActivity>,
): Promise<LoginActivity[]> {
return this.loginActivityRepo.find(filter);
return this.loginActivityHelperService.find(filter);
}

@authenticate(STRATEGY.BEARER, {
Expand All @@ -111,7 +105,7 @@ export class LoginActivityController {
@param.query.object('filter', getFilterSchemaFor(LoginActivity))
filter?: Filter<LoginActivity>,
): Promise<LoginActivity> {
return this.loginActivityRepo.findById(id, filter);
return this.loginActivityHelperService.findById(id, filter);
}

@authenticate(STRATEGY.BEARER, {
Expand Down Expand Up @@ -145,7 +139,7 @@ export class LoginActivityController {
if (filter) {
optionalWhere = await this.filterBuilder.buildActiveUsersFilter(filter);
}
const activeUsersForTime = await this.loginActivityRepo.find({
const activeUsersForTime = await this.loginActivityHelperService.find({
where: {
loginTime: {between: [startDate, endDate]},
...optionalWhere,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class LoginActivity extends CoreEntity<LoginActivity> {
type: 'string',
name: 'tenant_id',
})
tenantId?: string;
tenantId: string;

@property({
type: 'date',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import {inject} from '@loopback/context';
import {AnyObject, DataObject, Model, repository} from '@loopback/repository';
import {
HttpErrors,
RequestContext,
get,
getModelSchemaRef,
HttpErrors,
param,
patch,
post,
requestBody,
RequestContext,
} from '@loopback/rest';
import {
AuthenticateErrorKeys,
Expand All @@ -30,14 +30,14 @@ import {
import crypto from 'crypto';
import * as jwt from 'jsonwebtoken';
import {
authenticate,
authenticateClient,
AuthenticationBindings,
AuthErrorKeys,
AuthenticationBindings,
ClientAuthCode,
STRATEGY,
authenticate,
authenticateClient,
} from 'loopback4-authentication';
import {authorize, AuthorizeErrorKeys} from 'loopback4-authorization';
import {AuthorizeErrorKeys, authorize} from 'loopback4-authorization';
import moment from 'moment-timezone';
import {LoginType} from '../../../enums';
import {AuthServiceBindings} from '../../../keys';
Expand All @@ -52,8 +52,8 @@ import {
AuthCodeBindings,
AuthCodeGeneratorFn,
CodeReaderFn,
JwtPayloadFn,
JWTSignerFn,
JwtPayloadFn,
UserValidationServiceBindings,
} from '../../../providers';
import {
Expand Down
4 changes: 2 additions & 2 deletions services/authentication-service/src/repositories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import {LoginActivityRepository} from './login-activity.repository';
import {AuthClientRepository} from './auth-client.repository';
import {AuthSecureClientRepository} from './auth-secure-client.repository';
import {LoginActivityRepository} from './login-activity.repository';
import {OtpCacheRepository} from './otp-cache.repository';
import {OtpRepository} from './otp.repository';
import {RefreshTokenRepository} from './refresh-token.repository';
Expand All @@ -20,6 +20,7 @@ import {UserRepository} from './user.repository';

export * from './auth-client.repository';
export * from './auth-secure-client.repository';
export * from './login-activity.repository';
export * from './otp-cache.repository';
export * from './otp.repository';
export * from './refresh-token.repository';
Expand All @@ -32,7 +33,6 @@ export * from './user-level-permission.repository';
export * from './user-level-resource.repository';
export * from './user-tenant.repository';
export * from './user.repository';
export * from './login-activity.repository';

export const repositories = [
UserRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {Getter, inject} from '@loopback/core';
import {DefaultCrudRepository, juggler} from '@loopback/repository';
import {UserInToken} from '@sourceloop/core';
import {AuthenticationBindings} from 'loopback4-authentication';
import {LoginActivity} from '../models/login-activity.model';
import {AuthDbSourceName} from '../types';
import {LoginActivity} from '../models';
import {inject} from '@loopback/core';

export class LoginActivityRepository extends DefaultCrudRepository<
LoginActivity,
Expand All @@ -10,6 +12,8 @@ export class LoginActivityRepository extends DefaultCrudRepository<
constructor(
@inject(`datasources.${AuthDbSourceName}`)
dataSource: juggler.DataSource,
@inject.getter(AuthenticationBindings.CURRENT_USER)
public readonly getCurrentUser: Getter<UserInToken>,
) {
super(LoginActivity, dataSource);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {inject} from '@loopback/core';
import {Getter, inject} from '@loopback/core';
import {
SequelizeCrudRepository,
SequelizeDataSource,
} from '@loopback/sequelize';
import {UserInToken} from '@sourceloop/core';
import {AuthenticationBindings} from 'loopback4-authentication';
import {LoginActivity} from '../../models';
import {AuthDbSourceName} from '../../types';

Expand All @@ -13,6 +15,8 @@ export class LoginActivityRepository extends SequelizeCrudRepository<
constructor(
@inject(`datasources.${AuthDbSourceName}`)
dataSource: SequelizeDataSource,
@inject.getter(AuthenticationBindings.CURRENT_USER)
public readonly getCurrentUser: Getter<UserInToken>,
) {
super(LoginActivity, dataSource);
}
Expand Down
3 changes: 3 additions & 0 deletions services/authentication-service/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import {ActiveUserFilterBuilderService} from './active-user-fliter-builder.service';
import {LoginActivityHelperService} from './login-activity-helper.service';
import {LoginHelperService} from './login-helper.service';
import {OtpService} from './otp.service';
export * from './active-user-fliter-builder.service';
export * from './login-activity-helper.service';
export * from './login-helper.service';
export * from './otp.service';

export const services = [
LoginHelperService,
OtpService,
ActiveUserFilterBuilderService,
LoginActivityHelperService,
];
Loading

0 comments on commit e67280d

Please sign in to comment.