Fix eslint errors and update documentation

This commit is contained in:
Aaron Dalton 2023-11-22 16:18:49 -05:00
parent 1c6d13b34b
commit aecb22d7d5
7 changed files with 59 additions and 58 deletions

View File

@ -451,11 +451,14 @@ Auth can be configured on the service, bookmark, and widget level using the `all
- User3 - User3
``` ```
Auth for groups can be set in the `groups` under `auth`. Auth for groups can be set in the `groups` under `auth`. In general the `groups` tag follows the format of the `layout`
section. For example:
```yaml ```yaml
auth: auth:
groups: groups:
My Service Group: My Service Group:
allowGroups: ['Group1', 'Group2'] allowGroups: ['Group1', 'Group2']
My Other Group:
allowGroups: ['Group1']
``` ```

View File

@ -7,7 +7,7 @@ export default async function handler(req, res) {
try { try {
if (checkAllowedGroup(provider.permissions(req), groups, group)) { if (checkAllowedGroup(provider.permissions(req), groups, group)) {
res.json({ group: group}) res.json({group})
} else { } else {
res.status(401).json({message:"Group unathorized"}) res.status(401).json({message:"Group unathorized"})
} }

View File

@ -1,5 +1,5 @@
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
import useSWR, { unstable_serialize, SWRConfig } from "swr"; import useSWR, { unstable_serialize as unstableSerialize, SWRConfig } from "swr";
import Head from "next/head"; import Head from "next/head";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import classNames from "classnames"; import classNames from "classnames";
@ -9,6 +9,7 @@ import { BiError } from "react-icons/bi";
import { serverSideTranslations } from "next-i18next/serverSideTranslations"; import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import NullAuthProvider from "utils/auth/null";
import Tab, { slugify } from "components/tab"; import Tab, { slugify } from "components/tab";
import FileContent from "components/filecontent"; import FileContent from "components/filecontent";
import ServicesGroup from "components/services/group"; import ServicesGroup from "components/services/group";
@ -28,7 +29,7 @@ import themes from "utils/styles/themes";
import QuickLaunch from "components/quicklaunch"; import QuickLaunch from "components/quicklaunch";
import { getStoredProvider, searchProviders } from "components/widgets/search/search"; import { getStoredProvider, searchProviders } from "components/widgets/search/search";
import { fetchWithAuth, readAuthSettings } from "utils/auth/auth-helpers"; import { fetchWithAuth, readAuthSettings } from "utils/auth/auth-helpers";
import { NullAuthProvider } from "utils/auth/null";
const ThemeToggle = dynamic(() => import("components/toggles/theme"), { const ThemeToggle = dynamic(() => import("components/toggles/theme"), {
ssr: false, ssr: false,
}); });
@ -59,12 +60,12 @@ export async function getServerSideProps({req}) {
props: { props: {
initialSettings: settings, initialSettings: settings,
fallback: { fallback: {
[unstable_serialize(["/api/services", authContext])]: services, [unstableSerialize(["/api/services", authContext])]: services,
[unstable_serialize(["/api/bookmarks", authContext])]: bookmarks, [unstableSerialize(["/api/bookmarks", authContext])]: bookmarks,
[unstable_serialize(["/api/widgets", authContext])]: widgets, [unstableSerialize(["/api/widgets", authContext])]: widgets,
"/api/hash": false, "/api/hash": false,
}, },
authContext: authContext, authContext,
...(await serverSideTranslations(settings.language ?? "en")), ...(await serverSideTranslations(settings.language ?? "en")),
}, },
}; };
@ -77,12 +78,12 @@ export async function getServerSideProps({req}) {
props: { props: {
initialSettings: {}, initialSettings: {},
fallback: { fallback: {
[unstable_serialize(["/api/services", authContext])]: [], [unstableSerialize(["/api/services", authContext])]: [],
[unstable_serialize(["/api/bookmarks", authContext])]: [], [unstableSerialize(["/api/bookmarks", authContext])]: [],
[unstable_serialize(["/api/widgets", authContext])]: [], [unstableSerialize(["/api/widgets", authContext])]: [],
"/api/hash": false, "/api/hash": false,
}, },
authContext: authContext, authContext,
...(await serverSideTranslations("en")), ...(await serverSideTranslations("en")),
}, },
}; };

View File

@ -1,5 +1,5 @@
import { ProxyAuthProvider} from "./proxy"; import ProxyAuthProvider from "./proxy";
import { NullAuthProvider} from "./null"; import NullAuthProvider from "./null";
const AuthProviders = { const AuthProviders = {
NullAuthProvider, NullAuthProvider,
@ -7,7 +7,30 @@ const AuthProviders = {
}; };
function getProviderByKey(key) { function getProviderByKey(key) {
return AuthProviders.find((provider) => provider.key == key) ?? NullAuthProvider; return AuthProviders.find((provider) => provider.key === key) ?? NullAuthProvider;
}
function authAllow({user, groups}, item) {
const groupAllow = (('allowGroups' in item)) && groups.some(group => item.allowGroups.includes(group));
const userAllow = (('allowUsers' in item)) && item.allowUsers.includes(user);
const allowAll = (!('allowGroups' in item)) && (!('allowUsers' in item));
return userAllow || groupAllow || allowAll;
}
export function checkAllowedGroup(perms, authGroups, groupName) {
const testGroup = authGroups.find((group) => group.name === groupName )
return testGroup ? authAllow(perms, testGroup) : true
}
function filterAllowedItems(perms, authGroups, groups, groupKey) {
return groups.filter((group) => checkAllowedGroup(perms, authGroups, group.name))
.map((group) => ({
name: group.name,
[groupKey]: group[groupKey].filter((item) => authAllow(perms, item))
}))
.filter((group) => group[groupKey].length);
} }
export function readAuthSettings({provider, groups} = {}) { export function readAuthSettings({provider, groups} = {}) {
@ -25,33 +48,6 @@ export async function fetchWithAuth(key, context) {
return getProviderByKey(context.provider).fetch([key, context]); return getProviderByKey(context.provider).fetch([key, context]);
} }
export function checkAllowedGroup(perms, authGroups, groupName) {
testGroup = authGroups.find((group) => group.name == groupName )
return testGroup ? authAllow(perms, testGroup) : true
}
export const filterAllowedServices = (perms, authGroups, services) => filterAllowedItems(perms, authGroups, services, 'services'); export const filterAllowedServices = (perms, authGroups, services) => filterAllowedItems(perms, authGroups, services, 'services');
export const filterAllowedBookmarks = (perms, authGroups, bookmarks) => filterAllowedItems(perms, authGroups, bookmarks, 'bookmarks'); export const filterAllowedBookmarks = (perms, authGroups, bookmarks) => filterAllowedItems(perms, authGroups, bookmarks, 'bookmarks');
export const filterAllowedWidgets = (perms, widgets) => { export const filterAllowedWidgets = (perms, widgets) => widgets.filter((widget) => authAllow(perms, widget.options))
return widgets.filter((widget) => authItemFilter(perms, widget.options) )
}
function filterAllowedItems(perms, authGroups, groups, groupKey) {
return groups.filter((group) => checkAllowedGroup(perms, authGroups, group.name))
.map((group) => ({
name: group.name,
[groupKey]: group[groupKey].filter((item) => authAllow(perms, item))
}))
.filter((group) => group[groupKey].length);
}
function authAllow({user, groups}, item) {
const groupAllow = (('allowGroups' in item)) && groups.some(group => item.allowGroups.includes(group));
const userAllow = (('allowUsers' in item)) && item.allowUsers.includes(user);
const allowAll = (!('allowGroups' in item)) && (!('allowUsers' in item));
return userAllow || groupAllow || allowAll;
}

View File

@ -3,19 +3,21 @@ const NullAuthKey = "none"
function createNullAuth() { function createNullAuth() {
return { return {
authorize: (request) => NullPermissions, authorize: () => NullPermissions,
getContext: (request) => { return { getContext: () => ({
provider: NullAuthKey provider: NullAuthKey
} }, }),
} }
} }
async function fetchNullAuth([key, context]) { async function fetchNullAuth([key]) {
return fetch(key).then((res) => res.json()) return fetch(key).then((res) => res.json())
} }
export const NullAuthProvider = { const NullAuthProvider = {
key: NullAuthKey, key: NullAuthKey,
create: createNullAuth, create: createNullAuth,
fetch: fetchNullAuth fetch: fetchNullAuth
} }
export default NullAuthProvider;

View File

@ -3,21 +3,19 @@
const ProxyAuthKey="proxy" const ProxyAuthKey="proxy"
function getProxyPermissions(userHeader, groupHeader, request) { function getProxyPermissions(userHeader, groupHeader, request) {
const user = (userHeader)?request.headers.get(userHeader):None; const user = (userHeader)?request.headers.get(userHeader):null;
const groupsString = (groupHeader)?request.headers.get(groupHeader):""; const groupsString = (groupHeader)?request.headers.get(groupHeader):"";
return {user: user, groups: (groupsString)?groupsString.split(",").map((v) => v.trimStart()):[]} return {user, groups: (groupsString)?groupsString.split(",").map((v) => v.trimStart()):[]}
} }
function createProxyAuth({groupHeader, userHeader}) { function createProxyAuth({groupHeader, userHeader}) {
return { return {
getContext : (request) => { getContext : (request) => ({
return {
type: ProxyAuthKey, type: ProxyAuthKey,
...userHeader && {[userHeader]: request.headers.get(userHeader) }, ...userHeader && {[userHeader]: request.headers.get(userHeader) },
...groupHeader && {[groupHeader]: request.headers.get(groupHeader)} ...groupHeader && {[groupHeader]: request.headers.get(groupHeader)}
} }),
},
authorize : (request) => getProxyPermissions(userHeader, groupHeader, request) authorize : (request) => getProxyPermissions(userHeader, groupHeader, request)
} }
} }
@ -26,8 +24,10 @@ async function fetchProxyAuth([key, context]) {
return fetch(key, {headers: context.headers}).then((res) => res.json()) return fetch(key, {headers: context.headers}).then((res) => res.json())
} }
export const ProxyAuthProvider = { const ProxyAuthProvider = {
key: ProxyAuthKey, key: ProxyAuthKey,
create: createProxyAuth, create: createProxyAuth,
fetch: fetchProxyAuth fetch: fetchProxyAuth
} }
export default ProxyAuthProvider;

View File

@ -12,7 +12,6 @@ import {
servicesFromKubernetes, servicesFromKubernetes,
} from "utils/config/service-helpers"; } from "utils/config/service-helpers";
import { cleanWidgetGroups, widgetsFromConfig } from "utils/config/widget-helpers"; import { cleanWidgetGroups, widgetsFromConfig } from "utils/config/widget-helpers";
import { import {
filterAllowedBookmarks, filterAllowedBookmarks,
filterAllowedServices, filterAllowedServices,