Skip to content

Commit

Permalink
Merged in dspacecris7-DSC-280 (pull request #40)
Browse files Browse the repository at this point in the history
[DSC-280] Allow to turnoff completely the end user agreement (cherry-pick from CST-4803)

Approved-by: Giuseppe Digilio
  • Loading branch information
Davide Negretti authored and atarix83 committed Nov 11, 2021
2 parents a28e8d9 + af45685 commit f811fdc
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EndUserAgreementService } from './end-user-agreement.service';
import { Router, UrlTree } from '@angular/router';
import { EndUserAgreementCookieGuard } from './end-user-agreement-cookie.guard';
import { of } from 'rxjs';

describe('EndUserAgreementCookieGuard', () => {
let guard: EndUserAgreementCookieGuard;
Expand All @@ -10,7 +11,8 @@ describe('EndUserAgreementCookieGuard', () => {

beforeEach(() => {
endUserAgreementService = jasmine.createSpyObj('endUserAgreementService', {
isCookieAccepted: true
isCookieAccepted: true,
isUserAgreementEnabled: of(true),
});
router = jasmine.createSpyObj('router', {
navigateByUrl: {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import { Injectable } from '@angular/core';
import { AbstractEndUserAgreementGuard } from './abstract-end-user-agreement.guard';
import { Observable, of as observableOf } from 'rxjs';
import { Observable } from 'rxjs';
import { EndUserAgreementService } from './end-user-agreement.service';
import { Router } from '@angular/router';
import { map } from 'rxjs/operators';

/**
* A guard redirecting users to the end agreement page when the user agreement cookie hasn't been accepted
*/
@Injectable()
export class EndUserAgreementCookieGuard extends AbstractEndUserAgreementGuard {

constructor(protected endUserAgreementService: EndUserAgreementService,
protected router: Router) {
constructor(
protected endUserAgreementService: EndUserAgreementService,
protected router: Router,
) {
super(router);
}

/**
* True when the user agreement cookie has been accepted
*/
hasAccepted(): Observable<boolean> {
return observableOf(this.endUserAgreementService.isCookieAccepted());
return this.endUserAgreementService.isUserAgreementEnabled().pipe(
map((isUserAgreementEnabled) => isUserAgreementEnabled ? this.endUserAgreementService.isCookieAccepted() : true),
);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EndUserAgreementCurrentUserGuard } from './end-user-agreement-current-user.guard';
import { EndUserAgreementService } from './end-user-agreement.service';
import { Router, UrlTree } from '@angular/router';
import { of as observableOf } from 'rxjs';
import { of, of as observableOf } from 'rxjs';

describe('EndUserAgreementGuard', () => {
let guard: EndUserAgreementCurrentUserGuard;
Expand All @@ -11,7 +11,8 @@ describe('EndUserAgreementGuard', () => {

beforeEach(() => {
endUserAgreementService = jasmine.createSpyObj('endUserAgreementService', {
hasCurrentUserAcceptedAgreement: observableOf(true)
hasCurrentUserAcceptedAgreement: observableOf(true),
isUserAgreementEnabled: of(true),
});
router = jasmine.createSpyObj('router', {
navigateByUrl: {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Observable, of } from 'rxjs';
import { AbstractEndUserAgreementGuard } from './abstract-end-user-agreement.guard';
import { EndUserAgreementService } from './end-user-agreement.service';
import { Router } from '@angular/router';
import { switchMap } from 'rxjs/operators';

/**
* A guard redirecting logged in users to the end agreement page when they haven't accepted the latest user agreement
*/
@Injectable()
export class EndUserAgreementCurrentUserGuard extends AbstractEndUserAgreementGuard {

constructor(protected endUserAgreementService: EndUserAgreementService,
protected router: Router) {
constructor(
protected endUserAgreementService: EndUserAgreementService,
protected router: Router,
) {
super(router);
}

/**
* True when the currently logged in user has accepted the agreements or when the user is not currently authenticated
*/
hasAccepted(): Observable<boolean> {
return this.endUserAgreementService.hasCurrentUserAcceptedAgreement(true);
return this.endUserAgreementService.isUserAgreementEnabled().pipe(
switchMap((isUserAgreementEnabled) => isUserAgreementEnabled ?
this.endUserAgreementService.hasCurrentUserAcceptedAgreement(true) : of(true)
),
);
}

}
16 changes: 14 additions & 2 deletions src/app/core/end-user-agreement/end-user-agreement.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {
import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock';
import { of as observableOf } from 'rxjs';
import { EPerson } from '../eperson/models/eperson.model';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import {
createNoContentRemoteDataObject,
createSuccessfulRemoteDataObject$
} from '../../shared/remote-data.utils';
import { ConfigurationProperty } from '../shared/configuration-property.model';

describe('EndUserAgreementService', () => {
let service: EndUserAgreementService;
Expand All @@ -17,6 +21,7 @@ describe('EndUserAgreementService', () => {
let cookie;
let authService;
let ePersonService;
let configurationDataService;

beforeEach(() => {
userWithMetadata = Object.assign(new EPerson(), {
Expand All @@ -29,6 +34,10 @@ describe('EndUserAgreementService', () => {
}
});
userWithoutMetadata = Object.assign(new EPerson());
const configurationPropertyMock = Object.assign(new ConfigurationProperty(), {
values: ['false'],
});
const configurationPropertyMockRD$ = createNoContentRemoteDataObject<ConfigurationProperty>();

cookie = new CookieServiceMock();
authService = jasmine.createSpyObj('authService', {
Expand All @@ -39,8 +48,11 @@ describe('EndUserAgreementService', () => {
update: createSuccessfulRemoteDataObject$(userWithMetadata),
patch: createSuccessfulRemoteDataObject$({})
});
configurationDataService = jasmine.createSpyObj('configurationDataService', {
findByPropertyName: configurationPropertyMockRD$,
});

service = new EndUserAgreementService(cookie, authService, ePersonService);
service = new EndUserAgreementService(cookie, authService, ePersonService, configurationDataService);
});

describe('when the cookie is set to true', () => {
Expand Down
30 changes: 27 additions & 3 deletions src/app/core/end-user-agreement/end-user-agreement.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,43 @@ import { map, switchMap, take } from 'rxjs/operators';
import { hasValue } from '../../shared/empty.util';
import { EPersonDataService } from '../eperson/eperson-data.service';
import { getFirstCompletedRemoteData } from '../shared/operators';
import { ConfigurationDataService } from '../data/configuration-data.service';
import { calcPossibleSecurityContexts } from '@angular/compiler/src/template_parser/binding_parser';

export const END_USER_AGREEMENT_COOKIE = 'hasAgreedEndUser';
export const END_USER_AGREEMENT_METADATA_FIELD = 'dspace.agreements.end-user';
export const END_USER_AGREEMENT_ENABLED_PROPERTY = 'user-agreement.enabled';
export const END_USER_AGREEMENT_ENABLED_PROPERTY_DEFAULT = true;

/**
* Service for checking and managing the status of the current end user agreement
*/
@Injectable()
export class EndUserAgreementService {

constructor(protected cookie: CookieService,
protected authService: AuthService,
protected ePersonService: EPersonDataService) {
constructor(
protected cookie: CookieService,
protected authService: AuthService,
protected ePersonService: EPersonDataService,
protected configurationDataService: ConfigurationDataService,
) {
}

/**
* Check in remote configuration if user agreements are enabled
*/
isUserAgreementEnabled(): Observable<boolean> {
return this.configurationDataService.findByPropertyName(END_USER_AGREEMENT_ENABLED_PROPERTY).pipe(
getFirstCompletedRemoteData(),
// if property is undefined (or truthy but not 'true') return default value
map((res) => {
switch (res?.payload?.values[0]) {
case 'true': return true;
case 'false': return false;
default: return END_USER_AGREEMENT_ENABLED_PROPERTY_DEFAULT;
}
}),
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Store } from '@ngrx/store';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { of as observableOf } from 'rxjs';
import { of, of as observableOf } from 'rxjs';
import { By } from '@angular/platform-browser';
import { CoreState } from '../../core/core.reducers';
import { EPerson } from '../../core/eperson/models/eperson.model';
Expand Down Expand Up @@ -120,7 +120,8 @@ describe('CreateProfileComponent', () => {

endUserAgreementService = jasmine.createSpyObj('endUserAgreementService', {
isCookieAccepted: false,
removeCookieAccepted: {}
removeCookieAccepted: {},
isUserAgreementEnabled: of(true),
});

TestBed.configureTestingModule({
Expand Down
20 changes: 11 additions & 9 deletions src/app/register-page/create-profile/create-profile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,17 @@ export class CreateProfileComponent implements OnInit {
requireCertificate: false
};

// If the End User Agreement is accepted, add end-user agreement metadata to the user
if (this.userAgreementAccept) {
values.metadata[END_USER_AGREEMENT_METADATA_FIELD] = [
{
value: String(true)
}
];
this.endUserAgreementService.removeCookieAccepted();
}
// If the End User Agreement cookie is accepted, add end-user agreement metadata to the user
this.endUserAgreementService.isUserAgreementEnabled().subscribe((isUserAgreementEnabled) => {
if (isUserAgreementEnabled && this.userAgreementAccept) {
values.metadata[END_USER_AGREEMENT_METADATA_FIELD] = [
{
value: String(true)
}
];
this.endUserAgreementService.removeCookieAccepted();
}
});

const eperson = Object.assign(new EPerson(), values);
this.ePersonDataService.createEPersonForToken(eperson, this.token).pipe(
Expand Down

0 comments on commit f811fdc

Please sign in to comment.