Apply ACLs to internal oidc clients

This commit is contained in:
Johannes Zellner
2023-04-25 13:13:04 +02:00
parent debcf9c9e9
commit 5b6e6a556a
2 changed files with 49 additions and 12 deletions

View File

@@ -399,12 +399,10 @@ function renderInteractionPage(provider) {
return async function (req, res, next) {
try {
const { uid, prompt, params, session } = await provider.interactionDetails(req, res);
console.log('details', await provider.interactionDetails(req, res));
debug(`route interaction get uid:${uid} prompt.name:${prompt.name} client_id:${params.client_id} session:${session}`);
const [error, client] = await safe(clientsGet(params.client_id));
if (error) return next(error);
const client = await clientsGet(params.client_id);
switch (prompt.name) {
case 'login': {
@@ -414,10 +412,26 @@ function renderInteractionPage(provider) {
});
}
case 'consent': {
return res.render('interaction', {
submitUrl: `${ROUTE_PREFIX}/interaction/${uid}/confirm`,
name: client?.name || 'Cloudron'
});
const options = {
hasAccess: false,
submitUrl: '',
name: client?.name || ''
};
// check if user has access to the app if client refers to an app
if (client.appId) {
const app = await apps.get(client.appId);
const user = await users.get(session.accountId);
options.name = app.label || app.fqdn;
options.hasAccess = apps.canAccess(app, user);
} else {
options.hasAccess = true;
}
options.submitUrl = `${ROUTE_PREFIX}/interaction/${uid}/${options.hasAccess ? 'confirm' : 'abort'}`;
return res.render('interaction', options);
}
default:
return undefined;
@@ -442,7 +456,7 @@ function interactionLogin(provider) {
const prompt = details.prompt;
const name = prompt.name;
debug(`route interaction login post uid:${uid} prompt.name:${name}`, req.body);
debug(`route interaction login post uid:${uid} prompt.name:${name}`);
assert.equal(name, 'login');
@@ -482,15 +496,30 @@ function interactionConfirm(provider) {
return async function (req, res, next) {
try {
const interactionDetails = await provider.interactionDetails(req, res);
const { uid, prompt: { name, details }, params, session: { accountId } } = interactionDetails;
let { grantId, uid, prompt: { name, details }, params, session: { accountId } } = interactionDetails;
debug(`route interaction confirm post uid:${uid} prompt.name:${name} accountId:${accountId}`);
assert.equal(name, 'consent');
let { grantId } = interactionDetails;
let grant;
const client = await clientsGet(params.client_id);
// Check if user has access to the app if client refers to an app
// In most cases the user interaction already ends in the consent screen (see above)
if (client.appId) {
const app = await apps.get(client.appId);
const user = await users.get(accountId);
if (!apps.canAccess(app, user)) {
const result = {
error: 'access_denied',
error_description: 'User has no access to this app',
};
return await provider.interactionFinished(req, res, result, { mergeWithLastSubmission: false });
}
}
let grant;
if (grantId) {
// we'll be modifying existing grant in existing session
grant = await provider.Grant.find(grantId);

View File

@@ -26,15 +26,23 @@
<div class="col-md-12" style="text-align: center;">
<img width="128" height="128" style="margin-top: -84px" src="/api/v1/cloudron/avatar"/>
<br/>
<h1>Authorize <%= name %></h1>
<% if (hasAccess) { -%>
<h3>Authorize for <b><%= name %></b></h3>
<% } else { -%>
<h3>You do not have access to <b><%= name %></b></h3>
<% } -%>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-12 text-center">
<% if (hasAccess) { -%>
<form method="post" action="<%= submitUrl %>">
<button class="btn btn-primary btn-outline" type="submit">Authorize</button>
</form>
<% } else { -%>
<a class="btn btn-primary btn-outline" href="<%= submitUrl %>">Continue</a>
<% } -%>
</div>
</div>
</div>