Skip to content

Commit

Permalink
customer/uk-it-7 (#436)
Browse files Browse the repository at this point in the history
* ufal/fe-email-restricted-download (#430)

* ClarinAuthorization passed, but vanilla not because of vanilla check - I added dtoken into vanilla authorization url and because of that the vanilla authorization will be passed.

* Added message for the expiration token message - it was hardcoded.

* ufal/fe-not-show-shib-welcome-page

* Loaded property from the cfg and check if the page with idp attributes could be showed up. If not redirect the user to the home page. (#431)

* ufal/fe-s3-customization (#428)

* The admin could see in the bitstream admin UI if the bitstream is stored in both storages (S3, local).

* Fixed failing unit test - updated columnSizes object

* ufal/curate-translation-missing

Added curate collection edit translation and curation task name. (#434)

* ufal/upload-on-first-attempt-fix (#435)

* Moved file size limit into FileUploader options and handled Upload cancelation.

* Check that uploading is successful

* ufal/fe-show-checksum-result (#432)

* BitstreamChecksum values are fetched and parsed from the BE

* Checksum info is showed up.

* Added messages and translations.

* Added docs and refactored code

* Fixed failing tests

* Fixed wrong czech translations.

* ufal/shibboleth-redirect-from-login (#433)

* Send redirectUrl param to the IdP in the target url

* The code is updated to be more readable.

---------
Co-authored-by: Jozef Misutka <[email protected]>
  • Loading branch information
milanmajchrak authored Jan 3, 2024
1 parent 691ca71 commit f1c5545
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 46 deletions.
2 changes: 2 additions & 0 deletions cypress/integration/submission.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ describe('New Submission page', () => {

// Wait for upload to complete before proceeding
cy.wait('@upload');
// Check the upload success notice
cy.get('ds-notification').contains('Upload successful');
// Close the upload success notice
cy.get('[data-dismiss="alert"]').click({multiple: true});

Expand Down
6 changes: 4 additions & 2 deletions src/aai/aai.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
textHelpMore: "First check you are searching under the right country.\nIf your provider is not listed, please read <a href='https://lindat.mff.cuni.cz/how-do-i-sign-up' style='text-decoration: underline; font-weight: bold;'>these instructions</a> to obtain an account."
};
this.setup = function(options) {
var targetUrl = '';
var opts = jQuery.extend({}, this.defaults, options),
defaultCallback = function(e) {
window.location = opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target=' + opts.target + '&entityID=' + window.encodeURIComponent(e.entityID);
targetUrl = opts.target + '?redirectUrl=' + window.location.href;
window.location = opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target=' + targetUrl + '&entityID=' + window.encodeURIComponent(e.entityID);
};
//console.log(opts);
if(!opts.target){
Expand All @@ -33,7 +35,7 @@
opts.ourEntityID,
opts.responseUrl,
[ ],
opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target='+opts.target+'&entityID=');
opts.host + '/Shibboleth.sso/Login?SAMLDS=1&target=' + targetUrl + '&entityID=');
djc.discoPath = window.location.origin + (namespace === '' ? namespace : '/' + namespace) + "/assets/";
djc.metadata = [opts.metadataFeed];
djc.subtitle = "Login via Your home institution (e.g. university)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ export class ClarinBitstreamDownloadPageComponent implements OnInit {
this.requestService.send(headRequest);

const clarinIsAuthorized$ = this.rdbService.buildFromRequestUUID(requestId);
const isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanDownload, isNotEmpty(bitstream) ? bitstream.self : undefined);
// Clarin authorization will check dtoken parameter from the request
const dtoken = isNotEmpty(this.dtoken) ? '?dtoken=' + this.dtoken : '';
const isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanDownload, isNotEmpty(bitstream) ? bitstream.self + dtoken : undefined);
const isLoggedIn$ = this.auth.isAuthenticated();
return observableCombineLatest([clarinIsAuthorized$, isAuthorized$, isLoggedIn$, observableOf(bitstream)]);
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="jumbotron jumbotron-fluid bg-clarin-red rounded">
<div class="container">
<h1 class="display-4 px-3 py-3">The download token is expired, you will be redirected to the download page.</h1>
<h1 class="display-4 px-3 py-3">{{'clarin.bitstream.expired.dtoken.message' | translate}}</h1>
</div>
</div>
36 changes: 36 additions & 0 deletions src/app/core/bitstream-checksum-data.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Injectable } from '@angular/core';
import { dataService } from './data/base/data-service.decorator';
import { BaseDataService } from './data/base/base-data.service';
import { RequestService } from './data/request.service';
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from './core-state.model';
import { HALEndpointService } from './shared/hal-endpoint.service';
import { ObjectCacheService } from './cache/object-cache.service';
import { DefaultChangeAnalyzer } from './data/default-change-analyzer.service';
import { HttpClient } from '@angular/common/http';
import { NotificationsService } from '../shared/notifications/notifications.service';
import { linkName } from './data/clarin/clrua-data.service';
import { BitstreamChecksum } from './shared/bitstream-checksum.model';

/**
* A service responsible for fetching BitstreamChecksum objects from the REST API
*/
@Injectable()
@dataService(BitstreamChecksum.type)
export class BitstreamChecksumDataService extends BaseDataService<BitstreamChecksum> {
protected linkPath = 'checksum';

constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>,
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,
protected comparator: DefaultChangeAnalyzer<BitstreamChecksum>,
protected http: HttpClient,
protected notificationsService: NotificationsService,
) {
super(linkName, requestService, rdbService, objectCache, halService, undefined);
}
}
6 changes: 5 additions & 1 deletion src/app/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ import { ClarinUserMetadataDataService } from './data/clarin/clarin-user-metadat
import { ClarinLicenseResourceMappingService } from './data/clarin/clarin-license-resource-mapping-data.service';
import { ClarinVerificationTokenDataService } from './data/clarin/clarin-verification-token-data.service';
import { ClruaDataService } from './data/clarin/clrua-data.service';
import { BitstreamChecksum } from './shared/bitstream-checksum.model';
import { BitstreamChecksumDataService } from './bitstream-checksum-data.service';

/**
* When not in production, endpoint responses can be mocked for testing purposes
Expand Down Expand Up @@ -322,7 +324,8 @@ const PROVIDERS = [
OrcidQueueDataService,
OrcidHistoryDataService,
SupervisionOrderDataService,
HandleDataService
HandleDataService,
BitstreamChecksumDataService
];

/**
Expand All @@ -335,6 +338,7 @@ export const models =
Bundle,
Bitstream,
BitstreamFormat,
BitstreamChecksum,
Item,
Site,
Collection,
Expand Down
63 changes: 63 additions & 0 deletions src/app/core/shared/bitstream-checksum.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BITSTREAM_CHECKSUM } from './bitstream-checksum.resource';
import { excludeFromEquals } from '../utilities/equals.decorators';
import { autoserialize, deserialize } from 'cerialize';
import { ResourceType } from './resource-type';
import { HALLink } from './hal-link.model';
import { typedObject } from '../cache/builders/build-decorators';
import { TypedObject } from '../cache/typed-object.model';


/**
* Model class containing the checksums of a bitstream (local, S3, DB)
*/
@typedObject
export class BitstreamChecksum extends TypedObject {
/**
* The `bitstreamchecksum` object type.
*/
static type = BITSTREAM_CHECKSUM;

/**
* The object type
*/
@excludeFromEquals
@autoserialize
type: ResourceType;

/**
* The identifier of this BitstreamChecksum object
*/
@autoserialize
id: string;

/**
* The checksum of the active store (local/S3)
*/
@autoserialize
activeStore: CheckSum;

/**
* The checksum from the database
*/
@autoserialize
databaseChecksum: CheckSum;

/**
* The checksum of the synchronized store (S3, local)
*/
@autoserialize
synchronizedStore: CheckSum;

@deserialize
_links: {
self: HALLink
};
}

/**
* Model class containing a checksum value and algorithm
*/
export interface CheckSum {
checkSumAlgorithm: string;
value: string;
}
9 changes: 9 additions & 0 deletions src/app/core/shared/bitstream-checksum.resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ResourceType } from './resource-type';

/**
* The resource type for BitstreamChecksum
*
* Needs to be in a separate file to prevent circular
* dependencies in webpack.
*/
export const BITSTREAM_CHECKSUM = new ResourceType('bitstreamchecksum');
18 changes: 18 additions & 0 deletions src/app/core/shared/bitstream.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import { HALLink } from './hal-link.model';
import {BUNDLE} from './bundle.resource-type';
import {Bundle} from './bundle.model';
import { ChildHALResource } from './child-hal-resource.model';
import { BITSTREAM_CHECKSUM } from './bitstream-checksum.resource';
import { BitstreamChecksum } from './bitstream-checksum.model';

// Store number if the bitstream is stored in the both stores (S3 and local)
export const SYNCHRONIZED_STORES_NUMBER = 77;

@typedObject
@inheritSerialization(DSpaceObject)
Expand All @@ -34,6 +39,12 @@ export class Bitstream extends DSpaceObject implements ChildHALResource {
@autoserialize
bundleName: string;

/**
* The number of the store where the bitstream is store, it could be S3, local or both.
*/
@autoserialize
storeNumber: number;

/**
* The {@link HALLink}s for this Bitstream
*/
Expand All @@ -44,6 +55,7 @@ export class Bitstream extends DSpaceObject implements ChildHALResource {
format: HALLink;
content: HALLink;
thumbnail: HALLink;
checksum: HALLink;
};

/**
Expand All @@ -67,6 +79,12 @@ export class Bitstream extends DSpaceObject implements ChildHALResource {
@link(BUNDLE)
bundle?: Observable<RemoteData<Bundle>>;

/**
* The checksum values fetched from the DB, local and S3 store.
*/
@link(BITSTREAM_CHECKSUM)
checksum?: Observable<RemoteData<BitstreamChecksum>>;

getParentLinkKey(): keyof this['_links'] {
return 'format';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<div class="{{columnSizes.columns[1].buildClasses()}} row-element">{{'item.edit.bitstreams.headers.description' | translate}}</div>
<div class="{{columnSizes.columns[2].buildClasses()}} text-center row-element">{{'item.edit.bitstreams.headers.format' | translate}}</div>
<div class="{{columnSizes.columns[3].buildClasses()}} text-center row-element">{{'item.edit.bitstreams.headers.actions' | translate}}</div>
<div class="{{columnSizes.columns[4].buildClasses()}} text-center row-element">{{'item.edit.bitstreams.headers.synchronized' | translate}}</div>
</div>
<ds-item-edit-bitstream-bundle *ngFor="let bundle of bundles"
[bundle]="bundle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
// Description column
new ResponsiveColumnSizes(2, 3, 3, 3, 3),
// Format column
new ResponsiveColumnSizes(2, 2, 2, 2, 2),
new ResponsiveColumnSizes(1, 1, 1, 1, 1),
// Actions column
new ResponsiveColumnSizes(6, 5, 4, 3, 3)
new ResponsiveColumnSizes(5, 4, 3, 2, 2),
// Store synchronization columns
new ResponsiveColumnSizes(2, 2, 2, 2, 2)
]);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export class PaginatedDragAndDropBitstreamListComponent extends AbstractPaginate
switchMap(() => this.bundleService.getBitstreams(
this.bundle.id,
paginatedOptions,
followLink('format')
followLink('format'),
followLink('checksum')
))
);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,64 @@
</div>
</div>
</div>
<div class="{{columnSizes.columns[4].buildClasses()}} row-element d-flex align-items-center justify-content-center">
<div class="float-left d-flex align-items-center overflow-hidden">
<span class="text-center">
<i [class]="isBitstreamSynchronized() ? 'fas fa-check' : 'fas fa-times'"></i>
</span>
<span class="pl-1">|</span>
<div class="pl-1" [ngTemplateOutlet]="checksum"></div>
</div>
</div>
</ng-template>

<ng-template #checksum>
<div class="hover-container"
(mouseenter)="showChecksumValues = true"
(mouseleave)="showChecksumValues = false"
*ngVar="(checkSum$ | async) as bitstreamChecksum">
<i [class]="checksumsAreEqual(bitstreamChecksum) ? 'fas fa-check' : 'fas fa-times'"></i>
<i class="pl-2 fas fa-info-circle"
triggers="mouseenter:mouseleave"
[ngbPopover]="checksumPopover"
popoverTitle="Checksums"></i>
</div>
</ng-template>

<ng-template #checksumPopover>
<div *ngVar="(checkSum$ | async) as bitstreamChecksum">
<div>
<div class="font-weight-bold text-decoration-underline">
{{'item.edit.bitstreams.checksum.database' | translate}}
</div>
<div>
{{'item.edit.bitstreams.checksum.algorithm' | translate}} {{bitstreamChecksum.databaseChecksum.checkSumAlgorithm}}
</div>
<div>
{{'item.edit.bitstreams.checksum.value' | translate}} {{ bitstreamChecksum.databaseChecksum.value }}
</div>
</div>
<div>
<div class="font-weight-bold text-decoration-underline">
{{'item.edit.bitstreams.checksum.active-store' | translate}}
</div>
<div>
{{'item.edit.bitstreams.checksum.algorithm' | translate}} {{bitstreamChecksum.activeStore.checkSumAlgorithm}}
</div>
<div>
{{'item.edit.bitstreams.checksum.value' | translate}} {{ bitstreamChecksum.activeStore.value }}
</div>
</div>
<div *ngIf="isBitstreamSynchronized()">
<div class="font-weight-bold text-decoration-underline">
{{'item.edit.bitstreams.checksum.sync-store' | translate}}
</div>
<div>
{{'item.edit.bitstreams.checksum.algorithm' | translate}} {{bitstreamChecksum.synchronizedStore.checkSumAlgorithm}}
</div>
<div>
{{'item.edit.bitstreams.checksum.value' | translate}} {{ bitstreamChecksum.synchronizedStore.value }}
</div>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,38 @@ import { getBitstreamDownloadRoute } from '../../../../app-routing-paths';
import { By } from '@angular/platform-browser';
import { BrowserOnlyMockPipe } from '../../../../shared/testing/browser-only-mock.pipe';
import { RouterLinkDirectiveStub } from '../../../../shared/testing/router-link-directive.stub';
import { BitstreamChecksum } from '../../../../core/shared/bitstream-checksum.model';

let comp: ItemEditBitstreamComponent;
let fixture: ComponentFixture<ItemEditBitstreamComponent>;

const columnSizes = new ResponsiveTableSizes([
new ResponsiveColumnSizes(2, 2, 3, 4, 4),
new ResponsiveColumnSizes(2, 3, 3, 3, 3),
new ResponsiveColumnSizes(2, 2, 2, 2, 2),
new ResponsiveColumnSizes(6, 5, 4, 3, 3)
new ResponsiveColumnSizes(1, 1, 1, 1, 1),
new ResponsiveColumnSizes(5, 4, 3, 2, 2),
new ResponsiveColumnSizes(2, 2, 2, 2, 2)
]);

const format = Object.assign(new BitstreamFormat(), {
shortDescription: 'PDF'
});

const checksum = Object.assign(new BitstreamChecksum(), {
activeStore: {
checkSumAlgorithm: 'MD5',
value: '123'
},
synchronizedStore: {
checkSumAlgorithm: 'MD5',
value: '456'
},
databaseChecksum: {
checkSumAlgorithm: 'MD5',
value: '789'
}
});

const bitstream = Object.assign(new Bitstream(), {
uuid: 'bitstreamUUID',
name: 'Fake Bitstream',
Expand All @@ -37,7 +55,8 @@ const bitstream = Object.assign(new Bitstream(), {
content: { href: 'content-link' }
},

format: createSuccessfulRemoteDataObject$(format)
format: createSuccessfulRemoteDataObject$(format),
checksum: createSuccessfulRemoteDataObject$(checksum)
});
const fieldUpdate = {
field: bitstream,
Expand Down Expand Up @@ -81,7 +100,7 @@ describe('ItemEditBitstreamComponent', () => {
RouterLinkDirectiveStub
],
providers: [
{ provide: ObjectUpdatesService, useValue: objectUpdatesService }
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
], schemas: [
NO_ERRORS_SCHEMA
]
Expand Down
Loading

0 comments on commit f1c5545

Please sign in to comment.