Skip to content

Commit

Permalink
Showing 8 changed files with 35 additions and 21 deletions.
5 changes: 4 additions & 1 deletion grafana-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -21,4 +21,7 @@ grafana-plugin.yml

# Jest test report
jest_html_reporters.html
jest-html-reporters*
jest-html-reporters*

.turbo
tsconfig.tsbuildinfo
24 changes: 12 additions & 12 deletions grafana-plugin/e2e-tests/users/usersActions.test.ts
Original file line number Diff line number Diff line change
@@ -4,18 +4,6 @@ import { goToOnCallPage } from '../utils/navigation';
import { verifyThatUserCanViewOtherUsers, accessProfileTabs } from '../utils/users';

test.describe('Users screen actions', () => {
test("Admin is allowed to edit other users' profile", async ({ adminRolePage: { page } }) => {
await goToOnCallPage(page, 'users');
const editableUsers = page.getByTestId('users-table').getByRole('button', { name: 'Edit', disabled: false });
await editableUsers.first().waitFor();
const editableUsersCount = await editableUsers.count();
expect(editableUsersCount).toBeGreaterThan(1);
});

test('Admin is allowed to view the list of users', async ({ adminRolePage: { page } }) => {
await verifyThatUserCanViewOtherUsers(page);
});

test('Viewer is not allowed to view the list of users', async ({ viewerRolePage: { page } }) => {
await verifyThatUserCanViewOtherUsers(page, false);
});
@@ -66,6 +54,18 @@ test.describe('Users screen actions', () => {
expect(usersCountWithDisabledEdit).toBeGreaterThan(1);
});

test("Admin is allowed to edit other users' profile", async ({ adminRolePage: { page } }) => {
await goToOnCallPage(page, 'users');
const editableUsers = page.getByTestId('users-table').getByRole('button', { name: 'Edit', disabled: false });
await editableUsers.first().waitFor();
const editableUsersCount = await editableUsers.count();
expect(editableUsersCount).toBeGreaterThan(1);
});

test('Admin is allowed to view the list of users', async ({ adminRolePage: { page } }) => {
await verifyThatUserCanViewOtherUsers(page);
});

test('Search updates the table view', async ({ adminRolePage }) => {
const { page, userName } = adminRolePage;
await goToOnCallPage(page, 'users');
1 change: 1 addition & 0 deletions grafana-plugin/e2e-tests/utils/integrations.ts
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ export const createIntegration = async ({
await searchIntegrationAndAssertItsPresence({ page, integrationName });

await page.getByRole('link', { name: integrationName }).click();
await page.waitForLoadState('networkidle');
};

export const assignEscalationChainToIntegration = async (page: Page, escalationChainName: string): Promise<void> => {
4 changes: 2 additions & 2 deletions grafana-plugin/pkg/plugin/permissions.go
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ func (a *App) GetPermissions(settings *OnCallPluginSettings, onCallUser *OnCallU
if res.StatusCode == 200 {
var filtered []OnCallPermission
for _, permission := range permissions {
if strings.HasPrefix(permission.Action, "grafana-oncall-app") {
if strings.HasPrefix(permission.Action, settings.PluginID) {
filtered = append(filtered, permission)
}
}
@@ -65,7 +65,7 @@ func (a *App) GetAllPermissions(settings *OnCallPluginSettings) (map[string]map[

reqURL.Path += "api/access-control/users/permissions/search"
q := reqURL.Query()
q.Set("actionPrefix", "grafana-oncall-app")
q.Set("actionPrefix", settings.PluginID)
reqURL.RawQuery = q.Encode()

req, err := http.NewRequest("GET", reqURL.String(), nil)
11 changes: 10 additions & 1 deletion grafana-plugin/pkg/plugin/settings.go
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ type OnCallPluginSettings struct {
StackID int `json:"stack_id"`
OrgID int `json:"org_id"`
License string `json:"license"`
PluginID string `json:"plugin_id"`
GrafanaURL string `json:"grafana_url"`
GrafanaToken string `json:"grafana_token"`
RBACEnabled bool `json:"rbac_enabled"`
@@ -71,6 +72,9 @@ func (a *OnCallPluginSettings) Equal(b *OnCallPluginSettings) bool {
if a.License != b.License {
return false
}
if a.PluginID != b.PluginID {
return false
}
if a.GrafanaURL != b.GrafanaURL {
return false
}
@@ -127,6 +131,11 @@ func (a *App) OnCallSettingsFromContext(ctx context.Context) (*OnCallPluginSetti
GrafanaURL: pluginSettingsJson.GrafanaURL,
}

settings.PluginID = pluginContext.PluginID
if settings.PluginID == "" {
return nil, fmt.Errorf("OnCallSettingsFromContext: couldn't get plugin ID from plugin context")
}

version := pluginContext.PluginVersion
if version == "" {
// older Grafana versions do not have the plugin version in the context
@@ -286,7 +295,7 @@ func (a *App) SaveOnCallSettings(settings *OnCallPluginSettings) error {
return fmt.Errorf("Marshal OnCall settings JSON: %w", err)
}

settingsUrl, err := url.JoinPath(settings.GrafanaURL, fmt.Sprintf("api/plugins/grafana-oncall-app/settings"))
settingsUrl, err := url.JoinPath(settings.GrafanaURL, fmt.Sprintf("api/plugins/%s/settings", settings.PluginID))
if err != nil {
return err
}
4 changes: 3 additions & 1 deletion grafana-plugin/src/network/grafana-api/http-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getBackendSrv } from '@grafana/runtime';
import { OnCallPluginMetaJSONData } from 'types';

import { getPluginId } from 'utils/consts';

import {
ApiAuthKeyDTO,
NewApiKeyResult,
@@ -14,7 +16,7 @@ const KEYS_BASE_URL = '/api/auth/keys';
const SERVICE_ACCOUNTS_BASE_URL = '/api/serviceaccounts';
const ONCALL_KEY_NAME = 'OnCall';
const ONCALL_SERVICE_ACCOUNT_NAME = 'sa-autogen-OnCall';
const GRAFANA_PLUGIN_SETTINGS_URL = '/api/plugins/grafana-oncall-app/settings';
const GRAFANA_PLUGIN_SETTINGS_URL = `/api/plugins/${getPluginId()}/settings`;

export class GrafanaApiClient {
static grafanaBackend = getBackendSrv();
3 changes: 1 addition & 2 deletions grafana-plugin/src/utils/consts.ts
Original file line number Diff line number Diff line change
@@ -50,7 +50,6 @@ export const BREAKPOINT_TABS = 1024;
// Default redirect page
export const DEFAULT_PAGE = 'alert-groups';

export const PLUGIN_ID = 'grafana-oncall-app';
export const PLUGIN_ROOT = `/a/${getPluginId()}`;
export const PLUGIN_CONFIG = `/plugins/${getPluginId()}`;

@@ -82,7 +81,7 @@ const getGrafanaSubUrl = () => {

export const getOnCallApiPath = (subpath = '') => {
// We need to consider the grafanaSubUrl in case Grafana is served from subpath, e.g. http://localhost:3000/grafana
return `${getGrafanaSubUrl()}/api/plugins/${PLUGIN_ID}/resources${subpath}`;
return `${getGrafanaSubUrl()}/api/plugins/${getPluginId()}/resources${subpath}`;
};

// Faro
4 changes: 2 additions & 2 deletions grafana-plugin/src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import { isArray, concat, every, isEmpty, isObject, isPlainObject, flatMap, map,

import { isNetworkError } from 'network/network';

import { CLOUD_VERSION_REGEX, PLUGIN_ID } from './consts';
import { CLOUD_VERSION_REGEX, getPluginId } from './consts';

export class KeyValuePair<T = string | number> {
key: T;
@@ -153,7 +153,7 @@ export const isCurrentGrafanaVersionEqualOrGreaterThan = ({
);
};

export const getIsRunningOpenSourceVersion = () => !CLOUD_VERSION_REGEX.test(config.apps[PLUGIN_ID]?.version);
export const getIsRunningOpenSourceVersion = () => !CLOUD_VERSION_REGEX.test(config.apps[getPluginId()]?.version);

export const getIsExternalServiceAccountFeatureAvailable = () =>
isCurrentGrafanaVersionEqualOrGreaterThan({ minMajor: 10, minMinor: 3 }) &&

0 comments on commit 47478b5

Please sign in to comment.