Skip to content

Commit

Permalink
feat: can download metadata from openid-federation
Browse files Browse the repository at this point in the history
  • Loading branch information
damikael committed Feb 27, 2023
1 parent 1f4cd0c commit d253d8a
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/client/src/components/Breadcrumb/style.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.breadcrumb {
padding: 12px;
height: 50px;
}

.info-user {
Expand Down
6 changes: 3 additions & 3 deletions src/client/src/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ class MainService {
});
}

downloadMetadata(url, callback_response, callback_error) {
Utility.log("POST /api/metadata/download");
axios.post(config.basepath + '/api/metadata/download?apikey=' + Utility.getApikey(), {url: url})
downloadMetadata(url, type, callback_response, callback_error) {
Utility.log("POST /api/metadata/" + type + "/download");
axios.post(config.basepath + '/api/metadata/' + type + '/download?apikey=' + Utility.getApikey(), {url: url})
.then(function(response) {
Utility.log("downloadMetadata Success", response.data);
callback_response(response.data);
Expand Down
15 changes: 10 additions & 5 deletions src/client/src/views/MetadataDownload/MetadataDownload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MetadataDownload extends Component {
super(props);

this.state = {
type: "configuration", // configuration || federation
url: "https://",
configuration: ""
};
Expand All @@ -27,27 +28,27 @@ class MetadataDownload extends Component {
(info) => {
Utility.blockUI(false);
if(info.metadata && info.metadata.url && info.metadata.configuration) {
this.setState({ url: info.metadata.url, configuration: info.metadata.configuration });
this.setState({ url: info.metadata.url, type: info.metadata.type, configuration: info.metadata.configuration });
store.dispatch(Actions.setMetadataURL(info.metadata.url));
store.dispatch(Actions.setMetadataConfiguration(info.metadata.configuration));
}

if(info.metadata && info.metadata.url && !info.metadata.configuration) {
this.setState({ url: info.metadata.url });
this.setState({ url: info.metadata.url, type: info.metadata.type });
this.downloadMetadata(info.metadata.url);
}
},

(info)=> { // no session
Utility.blockUI(false);
if(info.metadata && info.metadata.url && info.metadata.configuration) {
this.setState({ url: info.metadata.url, configuration: info.metadata.configuration });
this.setState({ url: info.metadata.url, type: info.metadata.type, configuration: info.metadata.configuration });
store.dispatch(Actions.setMetadataURL(info.metadata.url));
store.dispatch(Actions.setMetadataConfiguration(info.metadata.configuration));
}

if(info.metadata && info.metadata.url && !info.metadata.configuration) {
this.setState({ url: info.metadata.url });
this.setState({ url: info.metadata.url, type: info.metadata.type });
this.downloadMetadata(info.metadata.url);
}
},
Expand All @@ -68,13 +69,17 @@ class MetadataDownload extends Component {
}


setType(type) {
this.setState({ type: type });
}

downloadMetadata(url) {
let service = Services.getMainService();
let store = ReduxStore.getMain();
let util = ReduxStore.getUtil();

Utility.blockUI(true);
service.downloadMetadata(url,
service.downloadMetadata(url, this.state.type,
(metadata) => {
Utility.blockUI(false);
this.setState({ url: metadata.url, configuration: metadata.configuration });
Expand Down
22 changes: 21 additions & 1 deletion src/client/src/views/MetadataDownload/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,28 @@ function view(me) {
<div className="main">
<div className="row">
<div className="col-sm-12 mb-3">
<label className="mb-3">
URL Type
</label>
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="check-type" id="type-configuration"
checked={me.state.type=='configuration'}
onChange={()=> { me.setType('configuration') }} />
<label class="form-check-label" for="flexRadioDefault1">
<strong>URL OIDC Core Configuration</strong> (.well-known/openid-configuration)
</label>
</div>
<div class="form-check mb-5">
<input class="form-check-input" type="radio" name="check-type" id="type-federation"
checked={me.state.type=='federation'}
onChange={()=> { me.setType('federation') }} />
<label class="form-check-label" for="flexRadioDefault2">
<strong>URL OpenID Federation</strong> (.well-known/openid-federation)
</label>
</div>

<label for="input-metadata" className="mb-3">
URL .well-known/openid-configuration
URL { (me.state.type=='configuration')? '.well-known/openid-configuration' : '.well-known/openid-federation' }
</label>
<input id="input-metadata"
type="text"
Expand Down
102 changes: 73 additions & 29 deletions src/server/api/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs-extra');
const axios = require('axios');
const moment = require('moment');
const validator = require('validator');
const jwt_decode = require('jwt-decode');
const Utility = require('../lib/utils');
const config_dir = require('../../config/dir.json');
const config_test = require("../../config/test.json");
Expand Down Expand Up @@ -80,8 +81,8 @@ module.exports = function(app, checkAuthorisation, database) {
*/

// download metadata
app.post("/api/metadata/download", function(req, res) {

app.post("/api/metadata/:type/download", function(req, res) {
// check if apikey is correct
let authorisation = checkAuthorisation(req);
if(!authorisation) {
Expand All @@ -95,40 +96,83 @@ module.exports = function(app, checkAuthorisation, database) {
let store_type = (authorisation=='API')? req.query.store_type : (req.session.store_type)? req.session.store_type : 'test';
let organization = (authorisation=='API')? req.body.organization : (req.session.entity)? req.session.entity.id : null;
let external_code = (authorisation=='API')? req.body.external_code : req.session.external_code;
let type = req.params.type;

if(!url) { return res.status(500).send("Please insert a valid URL"); }
if(!user) { return res.status(400).send("Parameter user is missing"); }
if(!store_type) { return res.status(400).send("Parameter store_type is missing"); }
//if(!organization) { return res.status(400).send("Parameter organization is missing"); }
//if(!external_code) { return res.status(400).send("Parameter external_code is missing"); }
if(type!='configuration' && type!='federation') return res.status(400).send('Metadata type MUST be configuration or federation');

if(type=='configuration') {
axios.get(url, {
responseType: "json",
})
.then(function(response) {
let configuration = response.data;
Utility.log(".well-known/openid-configuration", url);
console.log(configuration);

if(!validator.isJSON(JSON.stringify(configuration),
{ allow_primitives: true })) {
Utility.log("Error while parsing JSON");
throw "Error while parsing JSON";
}

let metadata = {
url: url,
type: 'configuration',
entity_statement: null,
configuration: configuration
};

database.setMetadata(user, external_code, store_type, metadata);
req.session.store.metadata = metadata;
res.status(200).json(metadata);
})
.catch(function(err) {
Utility.log("ERR /api/metadata/download", err);
res.status(500).send(err.toString());
});

} else if(type=='federation') {
axios.get(url, {
responseType: "application/entity-statement+jwt",
})
.then(function(response) {
let entity_statement = response.data;
Utility.log(".well-known/openid-federation", url);
console.log(entity_statement);

let decoded_entity_statement = jwt_decode(entity_statement);
let configuration = decoded_entity_statement['metadata']['openid_provider'];

if(!validator.isJSON(JSON.stringify(configuration),
{ allow_primitives: true })) {
Utility.log("Error while parsing JSON");
throw "Error while parsing JSON";
}

let metadata = {
url: url,
type: 'federation',
entity_statement: entity_statement,
configuration: configuration
};

database.setMetadata(user, external_code, store_type, metadata);
req.session.store.metadata = metadata;
res.status(200).json(metadata);
})
.catch(function(err) {
Utility.log("ERR /api/metadata/download", err);
res.status(500).send(err.toString());
});

axios.get(url, {
responseType: "json",
})
.then(function(response) {
let configuration = response.data;
Utility.log(".well-known/openid-configuration", url);
console.log(configuration);

if(!validator.isJSON(JSON.stringify(configuration),
{ allow_primitives: true })) {
Utility.log("Error while parsing JSON");
throw "Error while parsing JSON";
}

let metadata = {
url: url,
configuration: configuration
};

database.setMetadata(user, external_code, store_type, metadata);
req.session.store.metadata = metadata;
res.status(200).json(metadata);
})
.catch(function(err) {
Utility.log("ERR /api/metadata/download", err);
res.status(500).send(err.toString());
});
} else {
// other types not supported
}
});

// execute test for metadata
Expand Down
2 changes: 1 addition & 1 deletion src/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spid-oidc-check-op",
"version": "1.6.9",
"version": "1.7.0",
"description": "SPID OIDC Conformance Test Tool for OP",
"main": "spid-oidc-check-op",
"author": "Michele D'Amico (damikael) - AgID",
Expand Down

0 comments on commit d253d8a

Please sign in to comment.