mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-05 04:53:02 +00:00
@@ -12,8 +12,15 @@
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {SCAuthorizationProvider, SCBackendAggregationConfiguration, SCThingType} from '@openstapps/core';
|
||||
import {
|
||||
SCAboutPageContentType,
|
||||
SCAuthorizationProvider,
|
||||
SCBackendAggregationConfiguration,
|
||||
SCIndexResponse, SCSettingInputType, SCThingOriginType,
|
||||
SCThingType
|
||||
} from '@openstapps/core';
|
||||
import {Polygon} from 'geojson';
|
||||
import packageJson from "../../../../package.json";
|
||||
|
||||
// provides sample aggregations to be used in tests or backendless development
|
||||
export const sampleAggregations: SCBackendAggregationConfiguration[] = [
|
||||
@@ -118,3 +125,161 @@ export const sampleDefaultPolygon: Polygon = {
|
||||
],
|
||||
"type": "Polygon"
|
||||
}
|
||||
|
||||
const scVersion = packageJson.dependencies['@openstapps/core'];
|
||||
|
||||
export const sampleIndexResponse: SCIndexResponse = {
|
||||
app: {
|
||||
aboutPages: {
|
||||
about: {
|
||||
title: 'About',
|
||||
content: [
|
||||
{
|
||||
value: 'This is the about page',
|
||||
type: SCAboutPageContentType.MARKDOWN,
|
||||
translations: {
|
||||
en: {
|
||||
value: 'This is the about page',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
translations: {
|
||||
en: {
|
||||
title: 'About',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
campusPolygon: {
|
||||
coordinates: [[[1, 2]], [[1, 2]]],
|
||||
type: 'Polygon',
|
||||
},
|
||||
features: {},
|
||||
menus: [
|
||||
{
|
||||
icon: 'icon',
|
||||
id: 'main',
|
||||
items: [
|
||||
{
|
||||
icon: 'icon',
|
||||
route: '/index',
|
||||
title: 'start',
|
||||
translations: {
|
||||
de: {
|
||||
title: 'Start',
|
||||
},
|
||||
en: {
|
||||
title: 'start',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'main',
|
||||
translations: {
|
||||
de: {
|
||||
name: 'Haupt',
|
||||
},
|
||||
en: {
|
||||
name: 'main',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'StApps',
|
||||
privacyPolicyUrl: 'foo.bar',
|
||||
settings: [
|
||||
{
|
||||
categories: ['credentials'],
|
||||
defaultValue: '',
|
||||
inputType: SCSettingInputType.Text,
|
||||
name: 'username',
|
||||
order: 0,
|
||||
origin: {
|
||||
indexed: '2018-09-11T12:30:00Z',
|
||||
name: 'Dummy',
|
||||
type: SCThingOriginType.Remote,
|
||||
},
|
||||
translations: {
|
||||
de: {
|
||||
name: 'Benutzername',
|
||||
},
|
||||
en: {
|
||||
name: 'Username',
|
||||
},
|
||||
},
|
||||
type: SCThingType.Setting,
|
||||
uid: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
auth: {},
|
||||
backend: {
|
||||
SCVersion: scVersion,
|
||||
externalRequestTimeout: 5000,
|
||||
hiddenTypes: [SCThingType.DateSeries, SCThingType.Diff, SCThingType.Floor],
|
||||
mappingIgnoredTags: [],
|
||||
maxMultiSearchRouteQueries: 5,
|
||||
maxRequestBodySize: 512 * 1024,
|
||||
name: 'Technische Universität Berlin',
|
||||
namespace: '909a8cbc-8520-456c-b474-ef1525f14209',
|
||||
sortableFields: [
|
||||
{
|
||||
fieldName: 'name',
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'type',
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'categories',
|
||||
onlyOnTypes: [
|
||||
SCThingType.AcademicEvent,
|
||||
SCThingType.Building,
|
||||
SCThingType.Catalog,
|
||||
SCThingType.Dish,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.Building,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.Building,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'inPlace.geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.DateSeries,
|
||||
SCThingType.Dish,
|
||||
SCThingType.Floor,
|
||||
SCThingType.Organization,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
SCThingType.Ticket,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'offers',
|
||||
onlyOnTypes: [SCThingType.Dish],
|
||||
sortTypes: ['price'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
136
src/app/modules/auth/auth-helper.service.spec.ts
Normal file
136
src/app/modules/auth/auth-helper.service.spec.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2022 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {AuthHelperService} from './auth-helper.service';
|
||||
import {ConfigProvider} from '../config/config.provider';
|
||||
import {StorageProvider} from '../storage/storage.provider';
|
||||
import {DefaultAuthService} from './default-auth.service';
|
||||
import {Browser} from 'ionic-appauth';
|
||||
import {Requestor, StorageBackend} from '@openid/appauth';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {PAIAAuthService} from './paia/paia-auth.service';
|
||||
import {LoggerConfig, LoggerModule, NGXLogger} from 'ngx-logger';
|
||||
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
|
||||
describe('AuthHelperService', () => {
|
||||
let authHelperService: AuthHelperService;
|
||||
const storageProviderSpy = jasmine.createSpyObj('StorageProvider', [
|
||||
'init',
|
||||
'get',
|
||||
'has',
|
||||
'put',
|
||||
'search',
|
||||
]);
|
||||
const translateServiceSpy = jasmine.createSpyObj('TranslateService', [
|
||||
'setDefaultLang',
|
||||
'use',
|
||||
]);
|
||||
const defaultAuthServiceMock = jasmine.createSpyObj('DefaultAuthService', [
|
||||
'init',
|
||||
'setupConfiguration',
|
||||
]);
|
||||
const paiaAuthServiceMock = jasmine.createSpyObj('PAIAAuthService', [
|
||||
'init',
|
||||
'setupConfiguration',
|
||||
]);
|
||||
const authHelperServiceMock = jasmine.createSpyObj('AuthHelperService', [
|
||||
'constructor',
|
||||
]);
|
||||
const configProvider = jasmine.createSpyObj('ConfigProvider', {
|
||||
getAnyValue: {
|
||||
default: {
|
||||
endpoints: {
|
||||
mapping: {
|
||||
id: '$.id',
|
||||
email: '$.attributes.mailPrimaryAddress',
|
||||
givenName: '$.attributes.givenName',
|
||||
familyName: '$.attributes.sn',
|
||||
name: '$.attributes.sn',
|
||||
role: '$.attributes.eduPersonPrimaryAffiliation',
|
||||
studentId: '$.attributes.employeeNumber',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientModule, LoggerModule],
|
||||
providers: [
|
||||
NGXLogger,
|
||||
StAppsWebHttpClient,
|
||||
LoggerConfig,
|
||||
{
|
||||
provide: TranslateService,
|
||||
useValue: translateServiceSpy,
|
||||
},
|
||||
{
|
||||
provide: StorageProvider,
|
||||
useValue: storageProviderSpy,
|
||||
},
|
||||
{
|
||||
provider: DefaultAuthService,
|
||||
useValue: defaultAuthServiceMock,
|
||||
},
|
||||
{
|
||||
provider: PAIAAuthService,
|
||||
useValue: paiaAuthServiceMock,
|
||||
},
|
||||
{
|
||||
provide: ConfigProvider,
|
||||
useValue: configProvider,
|
||||
},
|
||||
Browser,
|
||||
StorageBackend,
|
||||
Requestor,
|
||||
{
|
||||
provider: AuthHelperService,
|
||||
useValue: authHelperServiceMock,
|
||||
},
|
||||
],
|
||||
});
|
||||
authHelperService = TestBed.inject(AuthHelperService);
|
||||
});
|
||||
|
||||
describe('getUserFromUserInfo', () => {
|
||||
it('should provide user configuration from userInfo', async () => {
|
||||
const userConfiguration = authHelperService.getUserFromUserInfo({
|
||||
attributes: {
|
||||
eduPersonPrimaryAffiliation: 'student',
|
||||
employeeNumber: '123456',
|
||||
givenName: 'Erika',
|
||||
mailPrimaryAddress: 'emuster@anyschool.de',
|
||||
oauthClientId: '123-abc-123',
|
||||
sn: 'Musterfrau',
|
||||
uid: 'emuster',
|
||||
},
|
||||
id: 'emuster',
|
||||
client_id: '123-abc-123',
|
||||
});
|
||||
|
||||
expect(userConfiguration).toEqual({
|
||||
id: 'emuster',
|
||||
givenName: 'Erika',
|
||||
familyName: 'Musterfrau',
|
||||
name: 'Erika Musterfrau',
|
||||
email: 'emuster@anyschool.de',
|
||||
role: 'student',
|
||||
studentId: '123456',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,7 +2,6 @@ import {Injectable} from '@angular/core';
|
||||
import {IPAIAAuthAction} from './paia/paia-auth-action';
|
||||
import {AuthActions, IAuthAction} from 'ionic-appauth';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {JSONFile} from '@angular/cli/utilities/json-file';
|
||||
import {JSONPath} from 'jsonpath-plus';
|
||||
import {
|
||||
SCAuthorizationProvider,
|
||||
@@ -56,8 +55,12 @@ export class AuthHelperService {
|
||||
return message;
|
||||
}
|
||||
|
||||
getUserFromUserInfo(userInfo: JSONFile) {
|
||||
const user: SCUserConfiguration = {id: '', name: '', role: 'student'};
|
||||
getUserFromUserInfo(userInfo: object) {
|
||||
const user: SCUserConfiguration = {
|
||||
id: '',
|
||||
name: '',
|
||||
role: 'student',
|
||||
};
|
||||
for (const key in this.userConfigurationMap) {
|
||||
user[key as keyof SCUserConfiguration] = JSONPath({
|
||||
path: this.userConfigurationMap[
|
||||
@@ -67,6 +70,14 @@ export class AuthHelperService {
|
||||
preventEval: true,
|
||||
})[0];
|
||||
}
|
||||
if (
|
||||
user.givenName &&
|
||||
user.givenName.length > 0 &&
|
||||
user.familyName &&
|
||||
user.familyName.length > 0
|
||||
) {
|
||||
user.name = `${user.givenName} ${user.familyName}`;
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -13,13 +13,6 @@
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {
|
||||
SCAboutPageContentType,
|
||||
SCIndexResponse,
|
||||
SCSettingInputType,
|
||||
SCThingOriginType,
|
||||
SCThingType,
|
||||
} from '@openstapps/core';
|
||||
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||
import {StorageProvider} from '../storage/storage.provider';
|
||||
import {ConfigProvider, STORAGE_KEY_CONFIG} from './config.provider';
|
||||
@@ -30,7 +23,7 @@ import {
|
||||
WrongConfigVersionInStorage,
|
||||
} from './errors';
|
||||
import {NGXLogger} from 'ngx-logger';
|
||||
import packageJson from '../../../../package.json';
|
||||
import {sampleIndexResponse} from '../../_helpers/data/sample-configuration';
|
||||
|
||||
describe('ConfigProvider', () => {
|
||||
let configProvider: ConfigProvider;
|
||||
@@ -192,161 +185,3 @@ describe('ConfigProvider', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const scVersion = packageJson.dependencies['@openstapps/core'];
|
||||
|
||||
const sampleIndexResponse: SCIndexResponse = {
|
||||
app: {
|
||||
aboutPages: {
|
||||
about: {
|
||||
title: 'About',
|
||||
content: [
|
||||
{
|
||||
value: 'This is the about page',
|
||||
type: SCAboutPageContentType.MARKDOWN,
|
||||
translations: {
|
||||
en: {
|
||||
value: 'This is the about page',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
translations: {
|
||||
en: {
|
||||
title: 'About',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
campusPolygon: {
|
||||
coordinates: [[[1, 2]], [[1, 2]]],
|
||||
type: 'Polygon',
|
||||
},
|
||||
features: {},
|
||||
menus: [
|
||||
{
|
||||
icon: 'icon',
|
||||
id: 'main',
|
||||
items: [
|
||||
{
|
||||
icon: 'icon',
|
||||
route: '/index',
|
||||
title: 'start',
|
||||
translations: {
|
||||
de: {
|
||||
title: 'Start',
|
||||
},
|
||||
en: {
|
||||
title: 'start',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'main',
|
||||
translations: {
|
||||
de: {
|
||||
name: 'Haupt',
|
||||
},
|
||||
en: {
|
||||
name: 'main',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
name: 'StApps',
|
||||
privacyPolicyUrl: 'foo.bar',
|
||||
settings: [
|
||||
{
|
||||
categories: ['credentials'],
|
||||
defaultValue: '',
|
||||
inputType: SCSettingInputType.Text,
|
||||
name: 'username',
|
||||
order: 0,
|
||||
origin: {
|
||||
indexed: '2018-09-11T12:30:00Z',
|
||||
name: 'Dummy',
|
||||
type: SCThingOriginType.Remote,
|
||||
},
|
||||
translations: {
|
||||
de: {
|
||||
name: 'Benutzername',
|
||||
},
|
||||
en: {
|
||||
name: 'Username',
|
||||
},
|
||||
},
|
||||
type: SCThingType.Setting,
|
||||
uid: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
auth: {},
|
||||
backend: {
|
||||
SCVersion: scVersion,
|
||||
externalRequestTimeout: 5000,
|
||||
hiddenTypes: [SCThingType.DateSeries, SCThingType.Diff, SCThingType.Floor],
|
||||
mappingIgnoredTags: [],
|
||||
maxMultiSearchRouteQueries: 5,
|
||||
maxRequestBodySize: 512 * 1024,
|
||||
name: 'Technische Universität Berlin',
|
||||
namespace: '909a8cbc-8520-456c-b474-ef1525f14209',
|
||||
sortableFields: [
|
||||
{
|
||||
fieldName: 'name',
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'type',
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'categories',
|
||||
onlyOnTypes: [
|
||||
SCThingType.AcademicEvent,
|
||||
SCThingType.Building,
|
||||
SCThingType.Catalog,
|
||||
SCThingType.Dish,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['ducet'],
|
||||
},
|
||||
{
|
||||
fieldName: 'geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.Building,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.Building,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'inPlace.geo',
|
||||
onlyOnTypes: [
|
||||
SCThingType.DateSeries,
|
||||
SCThingType.Dish,
|
||||
SCThingType.Floor,
|
||||
SCThingType.Organization,
|
||||
SCThingType.PointOfInterest,
|
||||
SCThingType.Room,
|
||||
SCThingType.Ticket,
|
||||
],
|
||||
sortTypes: ['distance'],
|
||||
},
|
||||
{
|
||||
fieldName: 'offers',
|
||||
onlyOnTypes: [SCThingType.Dish],
|
||||
sortTypes: ['price'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -38,7 +38,9 @@ export const STORAGE_KEY_CONFIG = 'stapps.config';
|
||||
/**
|
||||
* Provides configuration
|
||||
*/
|
||||
@Injectable()
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ConfigProvider {
|
||||
/**
|
||||
* Api client
|
||||
|
||||
@@ -50,8 +50,7 @@
|
||||
class="main-info"
|
||||
>
|
||||
<ion-text class="full-name">
|
||||
{{ userInfo?.givenName }}
|
||||
{{ userInfo?.familyName }}
|
||||
{{ userInfo?.name }}
|
||||
</ion-text>
|
||||
<div class="matriculation-number">
|
||||
<ion-label>
|
||||
@@ -65,7 +64,7 @@
|
||||
<ion-label>
|
||||
{{ 'profile.userInfo.username' | translate | uppercase }}
|
||||
</ion-label>
|
||||
<ion-text>{{ userInfo?.name }}</ion-text>
|
||||
<ion-text>{{ userInfo?.id }}</ion-text>
|
||||
</div>
|
||||
<div class="email">
|
||||
<ion-label>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
margin-left: calc(var(--spacing-md) * -4);
|
||||
object-position: left 50%;
|
||||
object-position: left bottom;
|
||||
}
|
||||
|
||||
.main-info {
|
||||
|
||||
Reference in New Issue
Block a user