Access control: service account role check (#47710)

* forbid setting role higher than user's role

* change response code

* can assign API key permissions to non-admin users

* add: assign viewer role directly upon creation

* refactor: add AddSATcommand infavor of AddAPIkey

* refactor: frontend fixes for ServiceAccountToken

Co-authored-by: eleijonmarck <eric.leijonmarck@gmail.com>
This commit is contained in:
Ieva
2022-04-13 18:11:03 +02:00
committed by GitHub
co-authored by eleijonmarck
parent f62c261900
commit a245531f0c
15 changed files with 64 additions and 38 deletions
@@ -15,17 +15,21 @@ import {
RadioButtonGroup,
useStyles2,
} from '@grafana/ui';
import { ApiKey, OrgRole } from 'app/types';
const EXPIRATION_OPTIONS = [
{ label: 'No expiration', value: false },
{ label: 'Set expiration date', value: true },
];
export type ServiceAccountToken = {
name: string;
secondsToLive: number;
};
interface CreateTokenModalProps {
isOpen: boolean;
token: string;
onCreateToken: (token: ApiKey) => void;
onCreateToken: (token: ServiceAccountToken) => void;
onClose: () => void;
}
@@ -95,7 +99,6 @@ export const CreateTokenModal = ({ isOpen, token, onCreateToken, onClose }: Crea
onClick={() =>
onCreateToken({
name: newTokenName,
role: OrgRole.Viewer,
secondsToLive: getSecondsToLive(newTokenExpirationDate),
})
}
@@ -17,7 +17,7 @@ import {
import { ServiceAccountTokensTable } from './ServiceAccountTokensTable';
import { getTimeZone, NavModel } from '@grafana/data';
import { Button } from '@grafana/ui';
import { CreateTokenModal } from './CreateServiceAccountTokenModal';
import { CreateTokenModal, ServiceAccountToken } from './CreateServiceAccountTokenModal';
import { contextSrv } from 'app/core/core';
interface OwnProps extends GrafanaRouteComponentProps<{ id: string }> {
@@ -86,7 +86,7 @@ const ServiceAccountPageUnconnected = ({
deleteServiceAccountToken(parseInt(match.params.id, 10), key.id!);
};
const onCreateToken = (token: ApiKey) => {
const onCreateToken = (token: ServiceAccountToken) => {
createServiceAccountToken(serviceAccount.id, token, setNewToken);
};
@@ -1,4 +1,4 @@
import { ApiKey, ServiceAccountDTO, ThunkResult, ServiceAccountFilter } from '../../../types';
import { ServiceAccountDTO, ThunkResult, ServiceAccountFilter } from '../../../types';
import { getBackendSrv, locationService } from '@grafana/runtime';
import {
acOptionsLoaded,
@@ -16,6 +16,7 @@ import {
import { accessControlQueryParam } from 'app/core/utils/accessControl';
import { fetchBuiltinRoles, fetchRoleOptions } from 'app/core/components/RolePicker/api';
import { debounce } from 'lodash';
import { ServiceAccountToken } from '../CreateServiceAccountTokenModal';
const BASE_URL = `/api/serviceaccounts`;
@@ -55,7 +56,7 @@ export function loadServiceAccount(saID: number): ThunkResult<void> {
export function createServiceAccountToken(
saID: number,
token: ApiKey,
token: ServiceAccountToken,
onTokenCreated: (key: string) => void
): ThunkResult<void> {
return async (dispatch) => {