Skip to content

Commit 3cd1566

Browse files
authored
TTA-102-prevent-an-admin-to-revoke-its-own-credentials (#930)
* Switch disabled to prevent admin from auto-revoke * added imports used in .ts to .spec.ts * fixed tests Co-authored-by: mmaquina <[email protected]>
1 parent 503b12e commit 3cd1566

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

src/app/modules/users/components/users-list/users-list.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<td class="col-3 text-center">
2121
<ui-switch
2222
size="small"
23+
[disabled]="checkRoleCurrentUser(user.email)"
2324
(change)="!isDevelopmentOrProd?switchGroup('time-tracker-admin', user):null; updateRole(ROLES.admin, user, $event);"
2425
[checked]="user.groups.includes('time-tracker-admin')"></ui-switch>
2526
admin

src/app/modules/users/components/users-list/users-list.component.spec.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
23
import { MockStore, provideMockStore } from '@ngrx/store/testing';
34
import { NgxPaginationModule } from 'ngx-pagination';
45
import { UsersListComponent } from './users-list.component';
@@ -7,12 +8,22 @@ import { ActionsSubject } from '@ngrx/store';
78
import { DataTablesModule } from 'angular-datatables';
89
import { GrantUserRole, RevokeUserRole } from '../../store/user.actions';
910
import { ROLES } from '../../../../../environments/environment';
11+
import { LoginService } from '../../../login/services/login.service';
12+
import { of } from 'rxjs';
13+
import { UserInfoService } from 'src/app/modules/user/services/user-info.service';
14+
1015

1116
describe('UsersListComponent', () => {
1217
let component: UsersListComponent;
1318
let fixture: ComponentFixture<UsersListComponent>;
1419
let store: MockStore<UserState>;
20+
let httpMock: HttpTestingController;
1521
const actionSub: ActionsSubject = new ActionsSubject();
22+
let loginService: LoginService;
23+
let userInfoService: UserInfoService;
24+
const userInfoServiceStub = {
25+
isAdmin: () => of(false),
26+
};
1627

1728
const state: UserState = {
1829
data: [
@@ -33,9 +44,11 @@ describe('UsersListComponent', () => {
3344
beforeEach(
3445
waitForAsync(() => {
3546
TestBed.configureTestingModule({
36-
imports: [NgxPaginationModule, DataTablesModule],
47+
imports: [NgxPaginationModule, DataTablesModule, HttpClientTestingModule],
3748
declarations: [UsersListComponent],
38-
providers: [provideMockStore({ initialState: state }), { provide: ActionsSubject, useValue: actionSub }],
49+
providers: [provideMockStore({ initialState: state }),
50+
{ provide: ActionsSubject, useValue: actionSub },
51+
{ providers: LoginService, useValue: {}},],
3952
}).compileComponents();
4053
})
4154
);
@@ -44,6 +57,9 @@ describe('UsersListComponent', () => {
4457
fixture = TestBed.createComponent(UsersListComponent);
4558
component = fixture.componentInstance;
4659
store = TestBed.inject(MockStore);
60+
httpMock = TestBed.inject(HttpTestingController);
61+
loginService = TestBed.inject(LoginService);
62+
userInfoService = TestBed.inject(UserInfoService);
4763
store.setState(state);
4864
fixture.detectChanges();
4965
});
@@ -229,9 +245,19 @@ describe('UsersListComponent', () => {
229245
expect(component.ROLES).toEqual(ROLES);
230246
});
231247

248+
it('Should call to localstorage and helper decode for get information about user when checkRoleCurrentUser method is called', () => {
249+
const account = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFiYyIsIm5hbWUiOiJhYmMiLCJlbWFpbCI6ImVtYWlsIiwiZ3JvdXBzIjpbImFkbWluIl19.gy1GljkoiuOjP8DzkoLRYE9SldBn5ljRc4kp8rwq7UI';
250+
spyOn(loginService, 'getLocalStorage').and.returnValue(account);
251+
spyOn(userInfoService, 'isAdmin').and.returnValue(of(true));
252+
const response = component.checkRoleCurrentUser('email')
253+
expect(response).toBeTrue();
254+
expect(userInfoService.isAdmin).toHaveBeenCalled();
255+
expect(loginService.getLocalStorage).toHaveBeenCalled();
256+
});
257+
232258
afterEach(() => {
233259
component.dtTrigger.unsubscribe();
234260
component.loadUsersSubscription.unsubscribe();
235261
fixture.destroy();
236262
});
237-
});
263+
});

src/app/modules/users/components/users-list/users-list.component.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import { EnvironmentType } from 'src/environments/enum';
99
import { User } from '../../models/users';
1010
import { LoadUsers, UserActionTypes, AddUserToGroup, RemoveUserFromGroup } from '../../store/user.actions';
1111
import { getIsLoading } from '../../store/user.selectors';
12+
import { UserInfoService } from 'src/app/modules/user/services/user-info.service';
13+
import { LoginService } from '../../../login/services/login.service';
14+
import { JwtHelperService } from '@auth0/angular-jwt';
1215

1316
@Component({
1417
selector: 'app-users-list',
@@ -28,13 +31,15 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
2831
};
2932
switchGroupsSubscription: Subscription;
3033
isDevelopmentOrProd = true;
34+
helper: JwtHelperService;
3135

3236
public get ROLES() {
3337
return ROLES;
3438
}
3539

36-
constructor(private store: Store<User>, private actionsSubject$: ActionsSubject) {
40+
constructor(private store: Store<User>, private actionsSubject$: ActionsSubject, private userInfoService: UserInfoService, private loginService: LoginService) {
3741
this.isLoading$ = store.pipe(delay(0), select(getIsLoading));
42+
this.helper = new JwtHelperService();
3843
}
3944

4045
ngOnInit(): void {
@@ -94,4 +99,11 @@ export class UsersListComponent implements OnInit, OnDestroy, AfterViewInit {
9499
)
95100
);
96101
}
102+
103+
checkRoleCurrentUser(userEmail: string){
104+
const token = this.loginService.getLocalStorage('user');
105+
const user = this.helper.decodeToken(token);
106+
return this.userInfoService.isAdmin() && (userEmail === user.email);
107+
}
108+
97109
}

0 commit comments

Comments
 (0)