Fix precommit isssues

This commit is contained in:
Aaron Dalton 2023-12-25 12:05:54 -05:00
parent 17451dd113
commit 0fed2f4267
10 changed files with 124 additions and 117 deletions

View File

@ -461,6 +461,7 @@ If either value is set to true, the error message will be hidden.
Basic auth integration is implemeted via an `auth` section. An auth provider can be configured using the `provider` section with the given type. Currently the only provider supported is `proxy`, where the users identification and group membership are passed via HTTP Request headers (in plaintext). The expectation is that the application will be accessed only via an authenticating proxy (i.e treafik ).
The group and user headers are both configurable like so:
```yaml
auth:
provider:
@ -490,7 +491,7 @@ section. For example:
auth:
groups:
My Service Group:
allowGroups: ['Group1', 'Group2']
allowGroups: ["Group1", "Group2"]
My Other Group:
allowGroups: ['Group1']
allowGroups: ["Group1"]
```

View File

@ -3,13 +3,13 @@ import { getSettings } from "utils/config/config";
export default async function handler(req, res) {
const { group } = req.query;
const { provider, groups } = readAuthSettings(getSettings().auth)
const { provider, groups } = readAuthSettings(getSettings().auth);
try {
if (checkAllowedGroup(provider.permissions(req), groups, group)) {
res.json({group})
res.json({ group });
} else {
res.status(401).json({message:"Group unathorized"})
res.status(401).json({ message: "Group unathorized" });
}
} catch (err) {
res.status(500).send("Error authenticating");

View File

@ -3,6 +3,6 @@ import { bookmarksResponse } from "utils/config/api-response";
import { getSettings } from "utils/config/config";
export default async function handler(req, res) {
const { provider, groups } = readAuthSettings(getSettings().auth)
const { provider, groups } = readAuthSettings(getSettings().auth);
res.send(await bookmarksResponse(provider.permissions(req), groups));
}

View File

@ -3,6 +3,6 @@ import { servicesResponse } from "utils/config/api-response";
import { getSettings } from "utils/config/config";
export default async function handler(req, res) {
const { provider, groups } = readAuthSettings(getSettings().auth)
const { provider, groups } = readAuthSettings(getSettings().auth);
res.send(await servicesResponse(provider.permissions(req), groups));
}

View File

@ -3,6 +3,6 @@ import { widgetsResponse } from "utils/config/api-response";
import { getSettings } from "utils/config/config";
export default async function handler(req, res) {
const { provider } = readAuthSettings(getSettings().auth)
const { provider } = readAuthSettings(getSettings().auth);
res.send(await widgetsResponse(provider.permissions(req)));
}

View File

@ -44,7 +44,7 @@ const Version = dynamic(() => import("components/version"), {
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "openmeteo", "search", "datetime"];
export async function getServerSideProps({req}) {
export async function getServerSideProps({ req }) {
let logger;
try {
logger = createLogger("index");
@ -160,7 +160,7 @@ function Index({ initialSettings, fallback, authContext }) {
return (
<SWRConfig value={{ fallback, fetcher: (resource, init) => fetch(resource, init).then((res) => res.json()) }}>
<ErrorBoundary>
<Home initialSettings={initialSettings} authContext={authContext}/>
<Home initialSettings={initialSettings} authContext={authContext} />
</ErrorBoundary>
</SWRConfig>
);
@ -530,7 +530,7 @@ export default function Wrapper({ initialSettings, fallback, authContext }) {
backgroundBrightness && `backdrop-brightness-${initialSettings.background.brightness}`,
)}
>
<Index initialSettings={initialSettings} fallback={fallback} authContext={authContext}/>
<Index initialSettings={initialSettings} fallback={fallback} authContext={authContext} />
</div>
</div>
</div>

View File

@ -3,51 +3,55 @@ import NullAuthProvider from "./null";
const AuthProviders = {
NullAuthProvider,
ProxyAuthProvider
ProxyAuthProvider,
};
function getProviderByKey(key) {
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));
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
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))
return groups
.filter((group) => checkAllowedGroup(perms, authGroups, group.name))
.map((group) => ({
name: group.name,
[groupKey]: group[groupKey].filter((item) => authAllow(perms, item))
[groupKey]: group[groupKey].filter((item) => authAllow(perms, item)),
}))
.filter((group) => group[groupKey].length);
}
export function readAuthSettings({provider, groups} = {}) {
export function readAuthSettings({ provider, groups } = {}) {
return {
provider: provider ? getProviderByKey(provider.type).create(provider) : NullAuthProvider.create(),
groups: groups ? groups.map((group) => ({
groups: groups
? groups.map((group) => ({
name: Object.keys(group)[0],
allowUsers: group[Object.keys(group)[0]].allowUsers,
allowGroups: group[Object.keys(group)[0]].allowGroups
})) : []
}
allowGroups: group[Object.keys(group)[0]].allowGroups,
}))
: [],
};
}
export async function fetchWithAuth(key, context) {
return getProviderByKey(context.provider).fetch([key, context]);
}
export const filterAllowedServices = (perms, authGroups, services) => filterAllowedItems(perms, authGroups, services, 'services');
export const filterAllowedBookmarks = (perms, authGroups, bookmarks) => filterAllowedItems(perms, authGroups, bookmarks, 'bookmarks');
export const filterAllowedWidgets = (perms, widgets) => widgets.filter((widget) => authAllow(perms, widget.options))
export const filterAllowedServices = (perms, authGroups, services) =>
filterAllowedItems(perms, authGroups, services, "services");
export const filterAllowedBookmarks = (perms, authGroups, bookmarks) =>
filterAllowedItems(perms, authGroups, bookmarks, "bookmarks");
export const filterAllowedWidgets = (perms, widgets) => widgets.filter((widget) => authAllow(perms, widget.options));

View File

@ -1,23 +1,23 @@
const NullPermissions = { user: null, groups:[]}
const NullAuthKey = "none"
const NullPermissions = { user: null, groups: [] };
const NullAuthKey = "none";
function createNullAuth() {
return {
authorize: () => NullPermissions,
getContext: () => ({
provider: NullAuthKey
provider: NullAuthKey,
}),
}
};
}
async function fetchNullAuth([key]) {
return fetch(key).then((res) => res.json())
return fetch(key).then((res) => res.json());
}
const NullAuthProvider = {
key: NullAuthKey,
create: createNullAuth,
fetch: fetchNullAuth
}
fetch: fetchNullAuth,
};
export default NullAuthProvider;

View File

@ -1,33 +1,33 @@
// 'proxy' auth provider is meant to be used by a reverse proxy that injects permission headers into the origin
// request. In this case we are relying on our proxy to authenitcate our users and validate.
const ProxyAuthKey="proxy"
const ProxyAuthKey = "proxy";
function getProxyPermissions(userHeader, groupHeader, request) {
const user = (userHeader)?request.headers.get(userHeader):null;
const groupsString = (groupHeader)?request.headers.get(groupHeader):"";
const user = userHeader ? request.headers.get(userHeader) : null;
const groupsString = groupHeader ? request.headers.get(groupHeader) : "";
return {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 {
getContext : (request) => ({
getContext: (request) => ({
type: ProxyAuthKey,
...userHeader && {[userHeader]: request.headers.get(userHeader) },
...groupHeader && {[groupHeader]: request.headers.get(groupHeader)}
...(userHeader && { [userHeader]: request.headers.get(userHeader) }),
...(groupHeader && { [groupHeader]: request.headers.get(groupHeader) }),
}),
authorize : (request) => getProxyPermissions(userHeader, groupHeader, request)
}
authorize: (request) => getProxyPermissions(userHeader, groupHeader, request),
};
}
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());
}
const ProxyAuthProvider = {
key: ProxyAuthKey,
create: createProxyAuth,
fetch: fetchProxyAuth
}
fetch: fetchProxyAuth,
};
export default ProxyAuthProvider;

View File

@ -12,11 +12,7 @@ import {
servicesFromKubernetes,
} from "utils/config/service-helpers";
import { cleanWidgetGroups, widgetsFromConfig } from "utils/config/widget-helpers";
import {
filterAllowedBookmarks,
filterAllowedServices,
filterAllowedWidgets
} from "utils/auth/auth-helpers";
import { filterAllowedBookmarks, filterAllowedServices, filterAllowedWidgets } from "utils/auth/auth-helpers";
/**
* Compares services by weight then by name.
@ -50,14 +46,16 @@ export async function bookmarksResponse(perms, authGroups) {
}
// map easy to write YAML objects into easy to consume JS arrays
const bookmarksArray = filterAllowedBookmarks(perms, authGroups,
const bookmarksArray = filterAllowedBookmarks(
perms,
authGroups,
bookmarks.map((group) => ({
name: Object.keys(group)[0],
bookmarks: group[Object.keys(group)[0]].map((entries) => ({
name: Object.keys(entries)[0],
...entries[Object.keys(entries)[0]][0],
})),
}))
})),
);
const sortedGroups = [];
@ -109,7 +107,11 @@ export async function servicesResponse(perms, authGroups) {
}
try {
discoveredKubernetesServices = filterAllowedServices(perms, authGroups, cleanServiceGroups(await servicesFromKubernetes()));
discoveredKubernetesServices = filterAllowedServices(
perms,
authGroups,
cleanServiceGroups(await servicesFromKubernetes()),
);
} catch (e) {
console.error("Failed to discover services, please check kubernetes.yaml for errors or remove example entries.");
if (e) console.error(e.toString());