Skip to content

Commit

Permalink
Merge branch 'main' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
akshaysasidrn committed Aug 18, 2022
2 parents 8137d29 + 6fe5e87 commit 0d64bf7
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 266 deletions.
144 changes: 79 additions & 65 deletions server/ee/services/oauth/oauth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { Organization } from 'src/entities/organization.entity';
import { OrganizationUser } from 'src/entities/organization_user.entity';
import { SSOConfigs } from 'src/entities/sso_config.entity';
import { User } from 'src/entities/user.entity';
import { DeepPartial } from 'typeorm';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
import { DeepPartial, EntityManager } from 'typeorm';
import { GitOAuthService } from './git_oauth.service';
import { GoogleOAuthService } from './google_oauth.service';
import UserResponse from './models/user_response';
Expand Down Expand Up @@ -52,7 +53,8 @@ export class OauthService {

async #findOrCreateUser(
{ firstName, lastName, email }: UserResponse,
organization: DeepPartial<Organization>
organization: DeepPartial<Organization>,
manager?: EntityManager
): Promise<User> {
const existingUser = await this.usersService.findByEmail(email, organization.id, ['active', 'invited']);
const organizationUser = existingUser?.organizationUsers?.[0];
Expand All @@ -61,20 +63,23 @@ export class OauthService {
// User not exist in the workspace
const { user, newUserCreated } = await this.usersService.findOrCreateByEmail(
{ firstName, lastName, email },
organization.id
organization.id,
manager
);

if (newUserCreated) {
await this.organizationUsersService.create(user, organization);
await this.organizationUsersService.create(user, organization, false, manager);
}
return user;
} else {
if (organizationUser.status !== 'active') await this.organizationUsersService.activate(organizationUser.id);
if (organizationUser.status !== 'active') {
await this.organizationUsersService.activate(organizationUser.id, manager);
}
return existingUser;
}
}

async #findAndActivateUser(email: string, organizationId: string): Promise<User> {
async #findAndActivateUser(email: string, organizationId: string, manager?: EntityManager): Promise<User> {
const user = await this.usersService.findByEmail(email, organizationId, ['active', 'invited']);
if (!user) {
throw new UnauthorizedException('User does not exist in the workspace');
Expand All @@ -84,7 +89,9 @@ export class OauthService {
if (!organizationUser) {
throw new UnauthorizedException('User does not exist in the workspace');
}
if (organizationUser.status !== 'active') await this.organizationUsersService.activate(organizationUser.id);
if (organizationUser.status !== 'active') {
await this.organizationUsersService.activate(organizationUser.id, manager);
}
return user;
}

Expand Down Expand Up @@ -207,70 +214,77 @@ export class OauthService {
let organizationDetails: DeepPartial<Organization>;
const isInstanceSSOLogin = !!(!configId && ssoType);

if (isInstanceSSOLogin && !organizationId) {
// Login from main login page
userDetails = await this.usersService.findByEmail(userResponse.email);

if (!userDetails && enableSignUp) {
// Create new user
let defaultOrganization: DeepPartial<Organization> = organization;

// Not logging in to specific organization, creating new
defaultOrganization = await this.organizationService.create('Untitled workspace');
await dbTransactionWrap(async (manager: EntityManager) => {
if (!isSingleOrganization && isInstanceSSOLogin && !organizationId) {
// Login from main login page - Multi-Workspace enabled
userDetails = await this.usersService.findByEmail(userResponse.email);

if (!userDetails && enableSignUp) {
// Create new user
let defaultOrganization: DeepPartial<Organization> = organization;

// Not logging in to specific organization, creating new
defaultOrganization = await this.organizationService.create('Untitled workspace', null, manager);

const groups = ['all_users', 'admin'];
userDetails = await this.usersService.create(
{
firstName: userResponse.firstName,
lastName: userResponse.lastName,
email: userResponse.email,
},
defaultOrganization.id,
groups,
null,
null,
null,
manager
);

await this.organizationUsersService.create(userDetails, defaultOrganization, false, manager);
organizationDetails = defaultOrganization;
} else if (!userDetails) {
throw new UnauthorizedException('User does not exist in the workspace');
} else if (userDetails.invitationToken) {
// User account setup not done, activating default organization
await this.usersService.updateUser(userDetails.id, { invitationToken: null }, manager);
await this.organizationUsersService.activate(userDetails.defaultOrganizationId, manager);
}

const groups = ['all_users', 'admin'];
userDetails = await this.usersService.create(
{
firstName: userResponse.firstName,
lastName: userResponse.lastName,
email: userResponse.email,
},
defaultOrganization.id,
groups
);

await this.organizationUsersService.create(userDetails, defaultOrganization);
organizationDetails = defaultOrganization;
} else if (!userDetails) {
throw new UnauthorizedException('User does not exist in the workspace');
} else if (userDetails.invitationToken) {
// User account setup not done, activating default organization
await this.usersService.updateUser(userDetails.id, { invitationToken: null });
await this.organizationUsersService.activate(userDetails.defaultOrganizationId);
}
if (!organizationDetails) {
// Finding organization to be loaded
const organizationList: Organization[] = await this.organizationService.findOrganizationWithLoginSupport(
userDetails,
'sso'
);

const defaultOrgDetails: Organization = organizationList?.find(
(og) => og.id === userDetails.defaultOrganizationId
);
if (defaultOrgDetails) {
// default organization SSO login enabled
organizationDetails = defaultOrgDetails;
} else if (organizationList?.length > 0) {
// default organization SSO login not enabled, picking first one from SSO enabled list
organizationDetails = organizationList[0];
} else {
// no SSO login enabled organization available for user - creating new one
organizationDetails = await this.organizationService.create('Untitled workspace', userDetails, manager);
}
}
} else {
userDetails = await (!enableSignUp
? this.#findAndActivateUser(userResponse.email, organization.id, manager)
: this.#findOrCreateUser(userResponse, organization, manager));

if (!organizationDetails) {
// Finding organization to be loaded
const organizationList: Organization[] = await this.organizationService.findOrganizationWithLoginSupport(
userDetails,
'sso'
);

const defaultOrgDetails: Organization = organizationList?.find(
(og) => og.id === userDetails.defaultOrganizationId
);
if (defaultOrgDetails) {
// default organization SSO login enabled
organizationDetails = defaultOrgDetails;
} else if (organizationList?.length > 0) {
// default organization SSO login not enabled, picking first one from SSO enabled list
organizationDetails = organizationList[0];
} else {
// no SSO login enabled organization available for user - creating new one
organizationDetails = await this.organizationService.create('Untitled workspace', userDetails);
if (!userDetails) {
throw new UnauthorizedException(`Email id ${userResponse.email} is not registered`);
}
}
} else {
userDetails = await (!enableSignUp
? this.#findAndActivateUser(userResponse.email, organization.id)
: this.#findOrCreateUser(userResponse, organization));

if (!userDetails) {
throw new UnauthorizedException(`Email id ${userResponse.email} is not registered`);
organizationDetails = organization;
}
});

organizationDetails = organization;
}
return await this.#generateLoginResultPayload(userDetails, organizationDetails, isInstanceSSOLogin);
}
}
Expand Down
14 changes: 5 additions & 9 deletions server/src/controllers/group_permissions.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,20 @@ export class GroupPermissionsController {
@Param('id') id: string,
@Param('appGroupPermissionId') appGroupPermissionId: string
) {
const groupPermission = await this.groupPermissionsService.updateAppGroupPermission(
await this.groupPermissionsService.updateAppGroupPermission(
user,
id,
appGroupPermissionId,
updateGroupPermissionDto.actions
);

return decamelizeKeys(groupPermission);
return;
}

@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can('accessGroupPermission', UserEntity))
@Put(':id')
async update(@User() user, @Param('id') id, @Body() body) {
const groupPermission = await this.groupPermissionsService.update(user, id, body);

return decamelizeKeys(groupPermission);
await this.groupPermissionsService.update(user, id, body);
}

@UseGuards(JwtAuthGuard, PoliciesGuard)
Expand All @@ -71,9 +68,8 @@ export class GroupPermissionsController {
@CheckPolicies((ability: AppAbility) => ability.can('accessGroupPermission', UserEntity))
@Delete(':id')
async destroy(@User() user, @Param('id') id) {
const groupPermission = await this.groupPermissionsService.destroy(user, id);

return decamelizeKeys(groupPermission);
await this.groupPermissionsService.destroy(user, id);
return;
}

@UseGuards(JwtAuthGuard, PoliciesGuard)
Expand Down
11 changes: 11 additions & 0 deletions server/src/helpers/utils.helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { QueryError } from 'src/modules/data_sources/query.errors';
import * as sanitizeHtml from 'sanitize-html';
import { EntityManager, getManager } from 'typeorm';

export function parseJson(jsonString: string, errorMessage?: string): object {
try {
Expand Down Expand Up @@ -52,3 +53,13 @@ export function sanitizeInput(value: string) {
export function lowercaseString(value: string) {
return value?.toLowerCase();
}

export async function dbTransactionWrap(operation: (...args) => any, manager?: EntityManager): Promise<any> {
if (manager) {
return await operation(manager);
} else {
return await getManager().transaction(async (manager) => {
return await operation(manager);
});
}
}
1 change: 1 addition & 0 deletions server/src/services/app_users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class AppUsersService {
private organizationUsersRepository: Repository<AppUser>
) {}

// TODO: remove deprecated
async create(user: User, appId: string, organizationUserId: string, role: string): Promise<AppUser> {
const organizationUser = await this.organizationUsersRepository.findOne({ where: { id: organizationUserId } });

Expand Down
23 changes: 17 additions & 6 deletions server/src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import { Organization } from 'src/entities/organization.entity';
import { ConfigService } from '@nestjs/config';
import { SSOConfigs } from 'src/entities/sso_config.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EntityManager, Repository } from 'typeorm';
import { OrganizationUser } from 'src/entities/organization_user.entity';
import { CreateUserDto } from '@dto/user.dto';
import { AcceptInviteDto } from '@dto/accept-organization-invite.dto';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
const bcrypt = require('bcrypt');
const uuid = require('uuid');

Expand Down Expand Up @@ -242,12 +243,22 @@ export class AuthService {
throw new NotAcceptableException();
}
}
// Create default organization
organization = await this.organizationsService.create('Untitled workspace');
const user = await this.usersService.create({ email }, organization.id, ['all_users', 'admin'], existingUser, true);
await this.organizationUsersService.create(user, organization, true);
await this.emailService.sendWelcomeEmail(user.email, user.firstName, user.invitationToken);

await dbTransactionWrap(async (manager: EntityManager) => {
// Create default organization
organization = await this.organizationsService.create('Untitled workspace', null, manager);
const user = await this.usersService.create(
{ email },
organization.id,
['all_users', 'admin'],
existingUser,
true,
null,
manager
);
await this.organizationUsersService.create(user, organization, true, manager);
await this.emailService.sendWelcomeEmail(user.email, user.firstName, user.invitationToken);
});
return {};
}

Expand Down
Loading

0 comments on commit 0d64bf7

Please sign in to comment.