Merge pull request #2479 from dpalou/MOBILE-3468

MOBILE-3468 login: Treat other URL schemes in QR in login
main
Juan Leyva 2020-08-25 16:30:15 +02:00 committed by GitHub
commit 2efd9f42cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 37 deletions

View File

@ -1557,6 +1557,7 @@
"core.errorsomedatanotdownloaded": "local_moodlemobileapp",
"core.errorsync": "local_moodlemobileapp",
"core.errorsyncblocked": "local_moodlemobileapp",
"core.errorurlschemeinvalidscheme": "local_moodlemobileapp",
"core.errorurlschemeinvalidsite": "local_moodlemobileapp",
"core.explanationdigitalminor": "moodle",
"core.favourites": "moodle",
@ -1750,6 +1751,7 @@
"core.login.erroraccesscontrolalloworigin": "local_moodlemobileapp",
"core.login.errordeletesite": "local_moodlemobileapp",
"core.login.errorexampleurl": "local_moodlemobileapp",
"core.login.errorqrnoscheme": "local_moodlemobileapp",
"core.login.errorupdatesite": "local_moodlemobileapp",
"core.login.faqcannotconnectanswer": "local_moodlemobileapp",
"core.login.faqcannotconnectquestion": "local_moodlemobileapp",

View File

@ -1557,6 +1557,7 @@
"core.errorsomedatanotdownloaded": "If you downloaded this activity, please notice that some data isn't downloaded during the download process for performance and data usage reasons.",
"core.errorsync": "An error occurred while synchronising. Please try again.",
"core.errorsyncblocked": "This {{$a}} cannot be synchronised right now because of an ongoing process. Please try again later. If the problem persists, try restarting the app.",
"core.errorurlschemeinvalidscheme": "This URL is meant to be used in another app: {{$a}}.",
"core.errorurlschemeinvalidsite": "This site URL cannot be opened in this app.",
"core.explanationdigitalminor": "This information is required to determine if your age is over the digital age of consent. This is the age when an individual can consent to terms and conditions and their data being legally stored and processed.",
"core.favourites": "Starred",
@ -1750,6 +1751,7 @@
"core.login.erroraccesscontrolalloworigin": "The cross-origin call you're trying to perform has been rejected. Please check https://docs.moodle.org/dev/Moodle_Mobile_development_using_Chrome_or_Chromium",
"core.login.errordeletesite": "An error occurred while deleting this site. Please try again.",
"core.login.errorexampleurl": "The URL https://campus.example.edu is only an example URL, it's not a real site. <strong>Please use the URL of your school or organization's site.</strong>",
"core.login.errorqrnoscheme": "This URL isn't a valid login URL.",
"core.login.errorupdatesite": "An error occurred while updating the site's token.",
"core.login.faqcannotconnectanswer": "Please, contact your site administrator.",
"core.login.faqcannotconnectquestion": "I typed my site address correctly but I still can't connect.",

View File

@ -25,6 +25,7 @@
"erroraccesscontrolalloworigin": "The cross-origin call you're trying to perform has been rejected. Please check https://docs.moodle.org/dev/Moodle_Mobile_development_using_Chrome_or_Chromium",
"errordeletesite": "An error occurred while deleting this site. Please try again.",
"errorexampleurl": "The URL https://campus.example.edu is only an example URL, it's not a real site. <strong>Please use the URL of your school or organization's site.</strong>",
"errorqrnoscheme": "This URL isn't a valid login URL.",
"errorupdatesite": "An error occurred while updating the site's token.",
"faqcannotconnectanswer": "Please, contact your site administrator.",
"faqcannotconnectquestion": "I typed my site address correctly but I still can't connect.",

View File

@ -20,6 +20,7 @@ import { CoreUtils } from '@providers/utils/utils';
import { CoreEventsProvider } from '@providers/events';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUrlUtils } from '@providers/utils/url';
import { CoreLoginHelperProvider } from '../../providers/helper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CoreConfigConstants } from '../../../../configconstants';
@ -324,6 +325,15 @@ export class CoreLoginCredentialsPage {
} catch (error) {
CoreCustomURLSchemes.instance.treatHandleCustomURLError(error);
}
} else if (text) {
// Not a custom URL scheme, check if it's a URL scheme to another app.
const scheme = CoreUrlUtils.instance.getUrlProtocol(text);
if (scheme && scheme != 'http' && scheme != 'https') {
this.domUtils.showErrorModal(this.translate.instant('core.errorurlschemeinvalidscheme', {$a: text}));
} else {
this.domUtils.showErrorModal('core.login.errorqrnoscheme', true);
}
}
}
}

View File

@ -429,10 +429,19 @@ export class CoreLoginSitePage {
}
}
} else {
// Not a custom URL scheme, put the text in the field.
// Not a custom URL scheme, check if it's a URL scheme to another app.
const scheme = this.urlUtils.getUrlProtocol(text);
if (scheme && scheme != 'http' && scheme != 'https') {
this.domUtils.showErrorModal(this.translate.instant('core.errorurlschemeinvalidscheme', {$a: text}));
} else if (this.loginHelper.isSiteUrlAllowed(text)) {
// Put the text in the field (if present).
this.siteForm.controls.siteUrl.setValue(text);
this.connect(new Event('click'), text);
} else {
this.domUtils.showErrorModal('core.errorurlschemeinvalidsite', true);
}
}
}
}

View File

@ -33,6 +33,7 @@ import { CoreConfigConstants } from '../../../configconstants';
import { CoreConstants } from '@core/constants';
import { Md5 } from 'ts-md5/dist/md5';
import { CoreSite } from '@classes/site';
import { CoreUrl } from '@singletons/url';
/**
* Data related to a SSO authentication.
@ -691,6 +692,35 @@ export class CoreLoginHelperProvider {
return false;
}
/**
* Check if a site URL is "allowed". In case the app has fixed sites, only those will be allowed to connect to.
*
* @param siteUrl Site URL to check.
* @return Promise resolved with boolean: whether is one of the fixed sites.
*/
async isSiteUrlAllowed(siteUrl: string): Promise<boolean> {
if (this.isFixedUrlSet()) {
// Only 1 site allowed.
return CoreUrl.sameDomainAndPath(siteUrl, <string> this.getFixedSites());
} else if (this.hasSeveralFixedSites()) {
const sites = <any[]> this.getFixedSites();
return sites.some((site) => {
return CoreUrl.sameDomainAndPath(siteUrl, site.url);
});
} else if (CoreConfigConstants.multisitesdisplay == 'sitefinder' && CoreConfigConstants.onlyallowlistedsites) {
// Call the sites finder to validate the site.
const result = await this.sitesProvider.findSites(siteUrl.replace(/^https?\:\/\/|\.\w{2,3}\/?$/g, ''));
return result && result.some((site) => {
return CoreUrl.sameDomainAndPath(siteUrl, site.url);
});
} else {
// No fixed sites or it uses a non-restrictive sites finder. Allow connecting.
return true;
}
}
/**
* Check if SSO login should use an embedded browser.
*

View File

@ -102,6 +102,7 @@
"errorsomedatanotdownloaded": "If you downloaded this activity, please notice that some data isn't downloaded during the download process for performance and data usage reasons.",
"errorsync": "An error occurred while synchronising. Please try again.",
"errorsyncblocked": "This {{$a}} cannot be synchronised right now because of an ongoing process. Please try again later. If the problem persists, try restarting the app.",
"errorurlschemeinvalidscheme": "This URL is meant to be used in another app: {{$a}}.",
"errorurlschemeinvalidsite": "This site URL cannot be opened in this app.",
"explanationdigitalminor": "This information is required to determine if your age is over the digital age of consent. This is the age when an individual can consent to terms and conditions and their data being legally stored and processed.",
"favourites": "Starred",

View File

@ -29,7 +29,6 @@ import { CoreSitePluginsProvider } from '@core/siteplugins/providers/siteplugins
import { CoreConfigConstants } from '../configconstants';
import { CoreConstants } from '@core/constants';
import { makeSingleton } from '@singletons/core.singletons';
import { CoreUrl } from '@singletons/url';
/**
* All params that can be in a custom URL scheme.
@ -167,7 +166,7 @@ export class CoreCustomURLSchemesProvider {
}
try {
const isValid = await this.isInFixedSiteUrls(data.siteUrl);
const isValid = await this.loginHelper.isSiteUrlAllowed(data.siteUrl);
if (!isValid) {
throw this.translate.instant('core.errorurlschemeinvalidsite');
@ -547,38 +546,6 @@ export class CoreCustomURLSchemesProvider {
this.domUtils.showErrorModalDefault(error.error, this.translate.instant('core.login.invalidsite'));
}
}
/**
* Check if a site URL is one of the fixed sites for the app (in case there are fixed sites).
*
* @param siteUrl Site URL to check.
* @return Promise resolved with boolean: whether is one of the fixed sites.
*/
protected async isInFixedSiteUrls(siteUrl: string): Promise<boolean> {
if (this.loginHelper.isFixedUrlSet()) {
return CoreUrl.sameDomainAndPath(siteUrl, <string> this.loginHelper.getFixedSites());
} else if (this.loginHelper.hasSeveralFixedSites()) {
const sites = <any[]> this.loginHelper.getFixedSites();
const site = sites.find((site) => {
return CoreUrl.sameDomainAndPath(siteUrl, site.url);
});
return !!site;
} else if (CoreConfigConstants.multisitesdisplay == 'sitefinder' && CoreConfigConstants.onlyallowlistedsites) {
// Call the sites finder to validate the site.
const result = await this.sitesProvider.findSites(siteUrl.replace(/^https?\:\/\/|\.\w{2,3}\/?$/g, ''));
const site = result && result.find((site) => {
return CoreUrl.sameDomainAndPath(siteUrl, site.url);
});
return !!site;
}
return true;
}
}
/**