mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ServiceAccounts: refactor UI (#49508)
* ServiceAccounts: refactor ServiceAccountRoleRow * Refactor ServiceAccountRoleRow * Refactor ServiceAccountProfile * Refactor components * Change service accounts icon * Refine service accounts page header * Improve service accounts filtering * Change delete button style * Tweak account id * Auto focus name field when create service account * Add disable/enable button * Enable/disable service accounts * Optimize updating service account (do not fetch all) * Remove status column (replace by enable/disable button) * Add banner with service accounts description * Add tokens from main page * Update tokens count when add token from main page * Fix action buttons column * Fix tokens count when change role * Refine table row classes * Fix buttons * Simplify working with state * Show message when service account updated * Able to filter disabled accounts * Mark disabled accounts in a table * Refine disabled account view * Move non-critical components to separate folder * Remove confusing focusing * Fix date picker position when creating new token * DatePicker: able to set minimum date that can be selected * Don't allow to select expiration dates prior today * Set tomorrow as a default token expiration date * Fix displaying expiration period * Rename Add token button * Refine page styles * Show modal when disabling SA from main page * Arrange role picker * Refine SA page styles * Generate default token name * More smooth navigation between SA pages * Stop loading indicator in case of error * Remove legacy styles usage * Tweaks after code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Get rid of useDisapatch in favor of mapDispatchToProps * Tests for ServiceAccountsListPage * Tests for service account page * Show new role picker only with license * Get rid of deprecated css classes * Apply suggestion from code review Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Fix service accounts icon * Tests for service account create page * Return service account info when update * Add behaviour tests for ServiceAccountsListPage * Fix disabled cursor on confirm button * More behavior tests for service account page * Temporary disable service account migration banner * Use safe where condition Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Apply review suggestions Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Remove autofocus from search Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> Co-authored-by: Jguer <joao.guerreiro@grafana.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/database"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
@@ -169,6 +170,13 @@ func (api *ServiceAccountsAPI) RetrieveServiceAccount(ctx *models.ReqContext) re
|
||||
metadata := api.getAccessControlMetadata(ctx, map[string]bool{saIDString: true})
|
||||
serviceAccount.AvatarUrl = dtos.GetGravatarUrlWithDefault("", serviceAccount.Name)
|
||||
serviceAccount.AccessControl = metadata[saIDString]
|
||||
|
||||
tokens, err := api.store.ListTokens(ctx.Req.Context(), serviceAccount.OrgId, serviceAccount.Id)
|
||||
if err != nil {
|
||||
api.log.Warn("Failed to list tokens for service account", "serviceAccount", serviceAccount.Id)
|
||||
}
|
||||
serviceAccount.Tokens = int64(len(tokens))
|
||||
|
||||
return response.JSON(http.StatusOK, serviceAccount)
|
||||
}
|
||||
|
||||
@@ -205,7 +213,12 @@ func (api *ServiceAccountsAPI) updateServiceAccount(c *models.ReqContext) respon
|
||||
resp.AvatarUrl = dtos.GetGravatarUrlWithDefault("", resp.Name)
|
||||
resp.AccessControl = metadata[saIDString]
|
||||
|
||||
return response.JSON(http.StatusOK, resp)
|
||||
return response.JSON(http.StatusOK, util.DynMap{
|
||||
"message": "Service account updated",
|
||||
"id": resp.Id,
|
||||
"name": resp.Name,
|
||||
"serviceaccount": resp,
|
||||
})
|
||||
}
|
||||
|
||||
// SearchOrgServiceAccountsWithPaging is an HTTP handler to search for org users with paging.
|
||||
@@ -222,10 +235,14 @@ func (api *ServiceAccountsAPI) SearchOrgServiceAccountsWithPaging(c *models.ReqC
|
||||
}
|
||||
// its okay that it fails, it is only filtering that might be weird, but to safe quard against any weird incoming query param
|
||||
onlyWithExpiredTokens := c.QueryBool("expiredTokens")
|
||||
onlyDisabled := c.QueryBool("disabled")
|
||||
filter := serviceaccounts.FilterIncludeAll
|
||||
if onlyWithExpiredTokens {
|
||||
filter = serviceaccounts.FilterOnlyExpiredTokens
|
||||
}
|
||||
if onlyDisabled {
|
||||
filter = serviceaccounts.FilterOnlyDisabled
|
||||
}
|
||||
serviceAccountSearch, err := api.store.SearchOrgServiceAccounts(ctx, c.OrgId, c.Query("query"), filter, page, perPage, c.SignedInUser)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get service accounts for current organization", err)
|
||||
|
||||
@@ -452,9 +452,10 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) {
|
||||
err := json.Unmarshal(actual.Body.Bytes(), &actualBody)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, scopeID, int(actualBody["id"].(float64)))
|
||||
assert.Equal(t, string(*tc.body.Role), actualBody["role"].(string))
|
||||
assert.Equal(t, *tc.body.Name, actualBody["name"].(string))
|
||||
assert.Equal(t, tc.user.Login, actualBody["login"].(string))
|
||||
serviceAccountData := actualBody["serviceaccount"].(map[string]interface{})
|
||||
assert.Equal(t, string(*tc.body.Role), serviceAccountData["role"].(string))
|
||||
assert.Equal(t, tc.user.Login, serviceAccountData["login"].(string))
|
||||
|
||||
// Ensure the user was updated in DB
|
||||
sa, err := saAPI.store.RetrieveServiceAccount(context.Background(), 1, int64(scopeID))
|
||||
|
||||
@@ -378,6 +378,11 @@ func (s *ServiceAccountsStoreImpl) SearchOrgServiceAccounts(
|
||||
whereConditions,
|
||||
"(SELECT count(*) FROM api_key WHERE api_key.service_account_id = org_user.user_id AND api_key.expires < ?) > 0")
|
||||
whereParams = append(whereParams, now)
|
||||
case serviceaccounts.FilterOnlyDisabled:
|
||||
whereConditions = append(
|
||||
whereConditions,
|
||||
"is_disabled = ?")
|
||||
whereParams = append(whereParams, s.sqlStore.Dialect.BooleanStr(true))
|
||||
default:
|
||||
s.log.Warn("invalid filter user for service account filtering", "service account search filtering", filter)
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ type ServiceAccountProfileDTO struct {
|
||||
AvatarUrl string `json:"avatarUrl" xorm:"-"`
|
||||
Role string `json:"role" xorm:"role"`
|
||||
Teams []string `json:"teams" xorm:"-"`
|
||||
Tokens int64 `json:"tokens,omitempty"`
|
||||
AccessControl map[string]bool `json:"accessControl,omitempty" xorm:"-"`
|
||||
}
|
||||
|
||||
@@ -74,5 +75,6 @@ type ServiceAccountFilter string // used for filtering
|
||||
|
||||
const (
|
||||
FilterOnlyExpiredTokens ServiceAccountFilter = "expiredTokens"
|
||||
FilterOnlyDisabled ServiceAccountFilter = "disabled"
|
||||
FilterIncludeAll ServiceAccountFilter = "all"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user