Access control: team UI improvements with FGAC (#45255)

* show teams page for user who can't list teams but can create teams

* Fixing buttons and routes

* Small refactor

Co-authored-by: gamab <gabi.mabs@gmail.com>
This commit is contained in:
Ieva
2022-02-11 09:58:37 +00:00
committed by GitHub
parent a12f2e1d19
commit 6fb3aac2e1
4 changed files with 27 additions and 13 deletions

View File

@@ -301,19 +301,23 @@ var orgsCreateAccessEvaluator = accesscontrol.EvalAll(
) )
// teamsAccessEvaluator is used to protect the "Configuration > Teams" page access // teamsAccessEvaluator is used to protect the "Configuration > Teams" page access
var teamsAccessEvaluator = accesscontrol.EvalAll( // grants access to a user when they can either create teams or can read and update a team
var teamsAccessEvaluator = accesscontrol.EvalAny(
accesscontrol.EvalPermission(accesscontrol.ActionTeamsCreate),
accesscontrol.EvalAll(
accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead), accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead),
accesscontrol.EvalAny( accesscontrol.EvalAny(
accesscontrol.EvalPermission(accesscontrol.ActionTeamsCreate),
accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite), accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite),
accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite), accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite),
), ),
),
) )
// teamsEditAccessEvaluator is used to protect the "Configuration > Teams > edit" page access // teamsEditAccessEvaluator is used to protect the "Configuration > Teams > edit" page access
var teamsEditAccessEvaluator = accesscontrol.EvalAll( var teamsEditAccessEvaluator = accesscontrol.EvalAll(
accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead), accesscontrol.EvalPermission(accesscontrol.ActionTeamsRead),
accesscontrol.EvalAny( accesscontrol.EvalAny(
accesscontrol.EvalPermission(accesscontrol.ActionTeamsCreate),
accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite), accesscontrol.EvalPermission(accesscontrol.ActionTeamsWrite),
accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite), accesscontrol.EvalPermission(accesscontrol.ActionTeamsPermissionsWrite),
), ),

View File

@@ -42,7 +42,10 @@ export class TeamList extends PureComponent<Props, State> {
} }
componentDidMount() { componentDidMount() {
// Don't fetch teams if the user cannot see any
if (contextSrv.hasAccess(AccessControlAction.ActionTeamsRead, true)) {
this.fetchTeams(); this.fetchTeams();
}
if (contextSrv.licensedAccessControlEnabled() && contextSrv.hasPermission(AccessControlAction.ActionRolesList)) { if (contextSrv.licensedAccessControlEnabled() && contextSrv.hasPermission(AccessControlAction.ActionRolesList)) {
this.fetchRoleOptions(); this.fetchRoleOptions();
} }
@@ -195,8 +198,10 @@ export class TeamList extends PureComponent<Props, State> {
renderList() { renderList() {
const { teamsCount, hasFetched } = this.props; const { teamsCount, hasFetched } = this.props;
// If the user cannot read any team, we didn't fetch them
let isLoading = !hasFetched && contextSrv.hasAccess(AccessControlAction.ActionTeamsRead, true);
if (!hasFetched) { if (isLoading) {
return null; return null;
} }
@@ -209,10 +214,12 @@ export class TeamList extends PureComponent<Props, State> {
render() { render() {
const { hasFetched, navModel } = this.props; const { hasFetched, navModel } = this.props;
// If the user cannot read any team, we didn't fetch them
let isLoading = !hasFetched && contextSrv.hasAccess(AccessControlAction.ActionTeamsRead, true);
return ( return (
<Page navModel={navModel}> <Page navModel={navModel}>
<Page.Contents isLoading={!hasFetched}>{this.renderList()}</Page.Contents> <Page.Contents isLoading={isLoading}>{this.renderList()}</Page.Contents>
</Page> </Page>
); );
} }

View File

@@ -33,17 +33,20 @@ export const TeamSettings: FC<Props> = ({ team, updateTeam }) => {
> >
{({ register }) => ( {({ register }) => (
<> <>
<Field label="Name"> <Field label="Name" disabled={!canWriteTeamSettings}>
<Input {...register('name', { required: true })} id="name-input" /> <Input {...register('name', { required: true })} id="name-input" />
</Field> </Field>
<Field <Field
label="Email" label="Email"
description="This is optional and is primarily used to set the team profile avatar (via gravatar service)." description="This is optional and is primarily used to set the team profile avatar (via gravatar service)."
disabled={!canWriteTeamSettings}
> >
<Input {...register('email')} placeholder="team@email.com" type="email" id="email-input" /> <Input {...register('email')} placeholder="team@email.com" type="email" id="email-input" />
</Field> </Field>
<Button type="submit">Update</Button> <Button type="submit" disabled={!canWriteTeamSettings}>
Update
</Button>
</> </>
)} )}
</Form> </Form>

View File

@@ -219,7 +219,7 @@ export function getAppRoutes(): RouteDescriptor[] {
roles: () => roles: () =>
contextSrv.evaluatePermission( contextSrv.evaluatePermission(
() => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']), () => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']),
[AccessControlAction.ActionTeamsRead] [AccessControlAction.ActionTeamsRead, AccessControlAction.ActionTeamsCreate]
), ),
component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList')), component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList')),
}, },
@@ -237,7 +237,7 @@ export function getAppRoutes(): RouteDescriptor[] {
roles: () => roles: () =>
contextSrv.evaluatePermission( contextSrv.evaluatePermission(
() => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']), () => (config.editorsCanAdmin ? ['Editor', 'Admin'] : ['Admin']),
[AccessControlAction.ActionTeamsWrite, AccessControlAction.ActionTeamsPermissionsWrite] [AccessControlAction.ActionTeamsRead]
), ),
component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages')), component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages')),
}, },