mirror of https://github.com/grafana/grafana.git
UserAdmin: Inform about enterprise user features (#106632)
* UserAdmin: Inform about enterprise user features * Update * Update * Update * Update * Update * New design * Update * Update * Update * Update * Update link * fix import * refactor to brand badge to component * Update * Update * Update * Update * Update links
This commit is contained in:
parent
5a8a04cb25
commit
ceee0b9c12
|
@ -91,7 +91,7 @@ const config = {
|
|||
},
|
||||
{
|
||||
url: '${HOST}/org/teams',
|
||||
threshold: 0,
|
||||
threshold: 1,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/plugins',
|
||||
|
|
|
@ -754,6 +754,7 @@ github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h
|
|||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
github.com/apache/arrow-go/v18 v18.0.1-0.20241212180703-82be143d7c30/go.mod h1:RNuWDIiGjq5nndL2PyQrndUy9nMLwheA3uWaAV7fe4U=
|
||||
github.com/apache/arrow-go/v18 v18.2.0/go.mod h1:Ic/01WSwGJWRrdAZcxjBZ5hbApNJ28K96jGYaxzzGUc=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 h1:q4dksr6ICHXqG5hm0ZW5IHyeEJXoIJSOZeBLmWPNeIQ=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40/go.mod h1:Q7yQnSMnLvcXlZ8RV+jwz/6y1rQTqbX6C82SndT52Zs=
|
||||
github.com/apache/arrow/go/v10 v10.0.1 h1:n9dERvixoC/1JjDmBcs9FPaEryoANa2sCgVFo6ez9cI=
|
||||
|
@ -885,6 +886,7 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpV
|
|||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||
github.com/chromedp/chromedp v0.9.2 h1:dKtNz4kApb06KuSXoTQIyUC2TrA0fhGDwNZf3bcgfKw=
|
||||
github.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
|
@ -1335,6 +1337,7 @@ github.com/grafana/grafana-plugin-sdk-go v0.263.0/go.mod h1:U43Cnrj/9DNYyvFcNdeU
|
|||
github.com/grafana/grafana-plugin-sdk-go v0.267.0/go.mod h1:OuwS4c/JYgn0rr/w5zhJBpLo4gKm/vw15RsfpYAvK9Q=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.269.1/go.mod h1:yv2KbO4mlr9WuDK2f+2gHAMTwwLmLuqaEnrPXTRU+OI=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.275.0/go.mod h1:mO9LJqdXDh5JpO/xIdPAeg5LdThgQ06Y/SLpXDWKw2c=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.277.0/go.mod h1:mAUWg68w5+1f5TLDqagIr8sWr1RT9h7ufJl5NMcWJAU=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250123151950-b066a6313173/go.mod h1:goSDiy3jtC2cp8wjpPZdUHRENcoSUHae1/Px/MDfddA=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250220154326-6e5de80ef295/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:q+h3HbmqU/PposW6lq8cMle1v8vuyX1LCMrGzbabHxc=
|
||||
|
@ -1366,6 +1369,8 @@ github.com/grafana/grafana/pkg/storage/unified/apistore v0.0.0-20250121113133-e7
|
|||
github.com/grafana/grafana/pkg/storage/unified/apistore v0.0.0-20250514132646-acbc7b54ed9e/go.mod h1:xrKQcxQxz+IUF90ybtfENFeEXtlj9nAsX/3Fw0KEIeQ=
|
||||
github.com/grafana/nanogit v0.0.0-20250616082354-5e94194d02ed h1:59JF1WhHLT+lNX89Tm1OzOEySMVMASAhaPbsRjtp8Kc=
|
||||
github.com/grafana/nanogit v0.0.0-20250616082354-5e94194d02ed/go.mod h1:OIAAKNgG5fpuJQRNO1lUSj9nc18Xl3O7M8fjIlBO1cI=
|
||||
github.com/grafana/nanogit v0.0.0-20250619160700-ebf70d342aa5 h1:MAQ2B0cu0V1S91ZjVa7NomNZFjaR2SmdtvdwhqBtyhU=
|
||||
github.com/grafana/nanogit v0.0.0-20250619160700-ebf70d342aa5/go.mod h1:tN93IZUaAmnSWgL0IgnKdLv6DNeIhTJGvl1wvQMrWco=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240930132144-b5e64e81e8d3 h1:6D2gGAwyQBElSrp3E+9lSr7k8gLuP3Aiy20rweLWeBw=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20240930132144-b5e64e81e8d3/go.mod h1:YeND+6FDA7OuFgDzYODN8kfPhXLCehcpxe4T9mdnpCY=
|
||||
github.com/grafana/prometheus-alertmanager v0.25.1-0.20250331083058-4563aec7a975 h1:4/BZkGObFWZf4cLbE2Vqg/1VTz67Q0AJ7LHspWLKJoQ=
|
||||
|
@ -1380,6 +1385,7 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr
|
|||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0/go.mod h1:zrT2dxOAjNFPRGjTUe2Xmb4q4YdUwVvQFV6xiCSf+z0=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc=
|
||||
|
@ -2329,6 +2335,7 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.5
|
|||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.58.0/go.mod h1:uosvgpqTcTXtcPQORTbEkZNDQTCDOgTz1fe6aLSyqrQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0/go.mod h1:54CaSNqYEXvpzDh8KPjiMVoWm60t5R0dZRt0leEPgAs=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
|
@ -2341,6 +2348,7 @@ go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs
|
|||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.35.0 h1:DpwKW04LkdFRFCIgM3sqwTJA/QREHMeMHYPWP1WeaPQ=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.35.0/go.mod h1:9+SNxwqvCWo1qQwUpACBY5YKNVxFJn5mlbXg/4+uKBg=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.35.0/go.mod h1:0ciyFyYZxE6JqRAQvIgGRabKWDUmNdW3GAQb6y/RlFU=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0/go.mod h1:iWS+NvC948FyfnJbVfPN9h/8+vr8CR2FPn6XsLRkvH8=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.29.0/go.mod h1:XAJmM2MWhiIoTO4LCLBVeE8w009TmsYk6hq1UNdXs5A=
|
||||
go.opentelemetry.io/contrib/zpages v0.60.0 h1:wOM9ie1Hz4H88L9KE6GrGbKJhfm+8F1NfW/Y3q9Xt+8=
|
||||
|
|
|
@ -15,6 +15,7 @@ func (f *HelpFlags1) AddFlag(flag HelpFlags1) { *f |= flag }
|
|||
const (
|
||||
HelpFlagGettingStartedPanelDismissed HelpFlags1 = 1 << iota
|
||||
HelpFlagDashboardHelp1
|
||||
HelpFlagEnterpriseAuth1
|
||||
)
|
||||
|
||||
type UpdateEmailActionType string
|
||||
|
|
|
@ -274,7 +274,10 @@ func (ss *sqlStore) Update(ctx context.Context, cmd *user.UpdateUserCommand) err
|
|||
q = q.UseBool("is_admin")
|
||||
usr.IsAdmin = v
|
||||
})
|
||||
setOptional(cmd.HelpFlags1, func(v user.HelpFlags1) { usr.HelpFlags1 = *cmd.HelpFlags1 })
|
||||
setOptional(cmd.HelpFlags1, func(v user.HelpFlags1) {
|
||||
q = q.MustCols("help_flags1")
|
||||
usr.HelpFlags1 = *cmd.HelpFlags1
|
||||
})
|
||||
|
||||
if _, err := q.Update(&usr); err != nil {
|
||||
return err
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import { css } from '@emotion/css';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaEdition } from '@grafana/data/internal';
|
||||
import { t, Trans } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Text, Stack, useStyles2, Button, LinkButton } from '@grafana/ui';
|
||||
import { CloudEnterpriseBadge } from 'app/core/components/Branding/CloudEnterpriseBadge';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
|
||||
export interface Props {
|
||||
page?: 'teams' | 'users';
|
||||
}
|
||||
|
||||
export function EnterpriseAuthFeaturesCard({ page }: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const helpFlags = contextSrv.user.helpFlags1;
|
||||
const HELP_FLAG_ENTERPRISE_AUTH = 0x0004;
|
||||
const [isDismissed, setDismissed] = useState<boolean>(Boolean(helpFlags & HELP_FLAG_ENTERPRISE_AUTH));
|
||||
|
||||
const onDismiss = () => {
|
||||
backendSrv
|
||||
.put(`/api/user/helpflags/${HELP_FLAG_ENTERPRISE_AUTH}`, undefined, { showSuccessAlert: false })
|
||||
.then((res) => {
|
||||
contextSrv.user.helpFlags1 = res.helpFlags1;
|
||||
setDismissed(true);
|
||||
});
|
||||
};
|
||||
|
||||
// This card is only visible in oss
|
||||
if (isDismissed || !isOpenSourceBuildOrUnlicenced()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.box}>
|
||||
<Stack direction="row" alignItems="center" justifyContent={'space-between'}>
|
||||
<CloudEnterpriseBadge />
|
||||
<Button
|
||||
variant="secondary"
|
||||
fill="text"
|
||||
icon="times"
|
||||
onClick={onDismiss}
|
||||
aria-label={t('admin.enterprise-auth-features-card.dismiss', 'Dismiss')}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack direction="column" gap={0.5}>
|
||||
<Text variant="h4">
|
||||
<Trans i18nKey="admin.enterprise-auth-features-card.heading">Enterprise authentication</Trans>
|
||||
</Text>
|
||||
<Text variant="body" color="secondary">
|
||||
<Trans i18nKey="admin.enterprise-auth-features-card.text">
|
||||
Manage users, teams, and permissions automatically with <strong>SAML</strong>, <strong>SCIM</strong>,{' '}
|
||||
<strong>LDAP</strong>, and <strong>RBAC</strong> — available in Grafana Cloud and Enterprise.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Stack>
|
||||
<div>
|
||||
<LinkButton
|
||||
href={`https://grafana.com/auth/sign-up/create-user?cloud-auth=&redirectPath=cloud-auth&utm_source=oss-grafana&cnt-admin-${page}`}
|
||||
icon="external-link-alt"
|
||||
variant="secondary"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Trans i18nKey="admin.enterprise-auth-features-card.learn-more-link">Learn more</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
cloudBadge: css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
background: theme.colors.gradients.brandHorizontal,
|
||||
color: theme.colors.primary.contrastText,
|
||||
padding: theme.spacing(0.5, 1),
|
||||
borderRadius: theme.shape.radius.pill,
|
||||
fontSize: theme.typography.bodySmall.fontSize,
|
||||
gap: theme.spacing(1),
|
||||
}),
|
||||
box: css({
|
||||
padding: theme.spacing(3),
|
||||
border: `1px solid ${theme.colors.border.weak}`,
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: theme.spacing(1.5),
|
||||
borderRadius: theme.shape.radius.default,
|
||||
marginTop: theme.spacing(3),
|
||||
strong: {
|
||||
color: theme.colors.text.primary,
|
||||
},
|
||||
}),
|
||||
icon: css({
|
||||
position: 'relative',
|
||||
top: -1,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function isOpenSourceBuildOrUnlicenced() {
|
||||
if (config.buildInfo.edition === GrafanaEdition.OpenSource) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (config.licenseInfo.stateInfo !== 'Licensed') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -11,6 +11,7 @@ import { contextSrv } from 'app/core/core';
|
|||
|
||||
import { AccessControlAction, StoreState, UserFilter } from '../../types';
|
||||
|
||||
import { EnterpriseAuthFeaturesCard } from './EnterpriseAuthFeaturesCard';
|
||||
import { UsersTable } from './Users/UsersTable';
|
||||
import { changeFilter, changePage, changeQuery, changeSort, fetchUsers } from './state/actions';
|
||||
|
||||
|
@ -118,6 +119,7 @@ const UserListAdminPageUnConnected = ({
|
|||
fetchData={changeSort}
|
||||
/>
|
||||
)}
|
||||
<EnterpriseAuthFeaturesCard page="users" />
|
||||
</Page.Contents>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -51,7 +51,7 @@ export function ProviderSAMLCard() {
|
|||
external
|
||||
variant="bodySmall"
|
||||
color="secondary"
|
||||
href="https://grafana.com/auth/sign-up/create-user?cloud-auth=&redirectPath=cloud-auth&utm_source=oss-authorization-admin"
|
||||
href="https://grafana.com/auth/sign-up/create-user?cloud-auth=&redirectPath=cloud-auth&utm_source=oss-grafana&cnt=admin-authorization-saml"
|
||||
>
|
||||
{t('auth-config.provider-card.saml-learn-more', 'Single sign-on (SSO) with SAML.')}
|
||||
</TextLink>
|
||||
|
@ -77,7 +77,7 @@ export function ProviderSCIMCard() {
|
|||
external
|
||||
variant="bodySmall"
|
||||
color="secondary"
|
||||
href="https://grafana.com/auth/sign-up/create-user?cloud-auth=&redirectPath=cloud-auth&utm_source=oss-authorization-admin"
|
||||
href="https://grafana.com/auth/sign-up/create-user?cloud-auth=&redirectPath=cloud-auth&utm_source=oss-grafana&cnt=admin-authorization-scim"
|
||||
>
|
||||
{t('auth-config.provider-card.scim-learn-more', ' Sync users and teams with SCIM.')}
|
||||
</TextLink>
|
||||
|
|
|
@ -13,6 +13,9 @@ jest.mock('app/core/core', () => ({
|
|||
contextSrv: {
|
||||
hasPermission: (action: string) => true,
|
||||
licensedAccessControlEnabled: () => false,
|
||||
user: {
|
||||
helpFlags1: 0,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import { contextSrv } from 'app/core/services/context_srv';
|
|||
import { AccessControlAction, Role, StoreState, TeamWithRoles } from 'app/types';
|
||||
|
||||
import { TeamRolePicker } from '../../core/components/RolePicker/TeamRolePicker';
|
||||
import { EnterpriseAuthFeaturesCard } from '../admin/EnterpriseAuthFeaturesCard';
|
||||
|
||||
import { deleteTeam, loadTeams, changePage, changeQuery, changeSort } from './state/actions';
|
||||
|
||||
|
@ -288,6 +289,7 @@ export const TeamList = ({
|
|||
)}
|
||||
</>
|
||||
)}
|
||||
{!query && <EnterpriseAuthFeaturesCard page="teams" />}
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
|
|
|
@ -110,6 +110,12 @@
|
|||
"update-button": "Update",
|
||||
"users-heading": "Organization users"
|
||||
},
|
||||
"enterprise-auth-features-card": {
|
||||
"dismiss": "Dismiss",
|
||||
"heading": "Enterprise authentication",
|
||||
"learn-more-link": "Learn more",
|
||||
"text": "Manage users, teams, and permissions automatically with <1>SAML</1>, <3>SCIM</3>, <6>LDAP</6>, and <8>RBAC</8> — available in Grafana Cloud and Enterprise."
|
||||
},
|
||||
"feature-listing": {
|
||||
"title-auditing": "Auditing",
|
||||
"title-custom-branding": "Custom branding",
|
||||
|
|
Loading…
Reference in New Issue