AuthN: User Quota (#61540)

* remove reqContext from quota checks in login

* add guards for nil ScopeParams
This commit is contained in:
Jo
2023-01-16 10:54:15 +00:00
committed by GitHub
parent a4c2237d16
commit dcfeab2c73
8 changed files with 30 additions and 8 deletions

View File

@@ -161,7 +161,7 @@ func (ss *sqlxStore) Count(ctx context.Context, scopeParams *quota.ScopeParamete
u.Set(tag, r.Count)
}
if scopeParams.OrgID != 0 {
if scopeParams != nil && scopeParams.OrgID != 0 {
if err := ss.sess.Get(ctx, &r, `SELECT COUNT(*) AS count FROM api_key WHERE org_id = ?`, scopeParams.OrgID); err != nil {
return u, err
} else {

View File

@@ -200,7 +200,7 @@ func (ss *sqlStore) Count(ctx context.Context, scopeParams *quota.ScopeParameter
u.Set(tag, r.Count)
}
if scopeParams.OrgID != 0 {
if scopeParams != nil && scopeParams.OrgID != 0 {
if err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := "SELECT COUNT(*) AS count FROM api_key WHERE org_id = ?"
if _, err := sess.SQL(rawSQL, scopeParams.OrgID).Get(&r); err != nil {

View File

@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/user"
)
@@ -44,6 +45,20 @@ func (s *UserSync) SyncUser(ctx context.Context, id *authn.Identity, _ *authn.Re
return login.ErrSignupNotAllowed
}
// quota check (FIXME: (jguer) this should be done in the user service)
// we may insert in both user and org_user tables
// therefore we need to query check quota for both user and org services
for _, srv := range []string{user.QuotaTargetSrv, org.QuotaTargetSrv} {
limitReached, errLimit := s.quotaService.CheckQuotaReached(ctx, quota.TargetSrv(srv), nil)
if errLimit != nil {
s.log.Warn("error getting user quota.", "error", errLimit)
return login.ErrGettingUserQuota
}
if limitReached {
return login.ErrUsersQuotaReached
}
}
// create user
var errCreate error
usr, errCreate = s.createUser(ctx, id)

View File

@@ -333,7 +333,7 @@ func (d *DashboardStore) Count(ctx context.Context, scopeParams *quota.ScopePara
u.Set(tag, r.Count)
}
if scopeParams.OrgID != 0 {
if scopeParams != nil && scopeParams.OrgID != 0 {
if err := d.store.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := fmt.Sprintf("SELECT COUNT(*) AS count FROM dashboard WHERE org_id=? AND is_folder=%s", d.store.GetDialect().BooleanStr(false))
if _, err := sess.SQL(rawSQL, scopeParams.OrgID).Get(&r); err != nil {

View File

@@ -198,7 +198,7 @@ func (ss *SqlStore) Count(ctx context.Context, scopeParams *quota.ScopeParameter
u.Set(tag, r.Count)
}
if scopeParams.OrgID != 0 {
if scopeParams != nil && scopeParams.OrgID != 0 {
if err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := "SELECT COUNT(*) AS count FROM data_source WHERE org_id=?"
if _, err := sess.SQL(rawSQL, scopeParams.OrgID).Get(&r); err != nil {

View File

@@ -62,10 +62,11 @@ func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUser
return login.ErrSignupNotAllowed
}
// quota check (FIXME: (jguer) this should be done in the user service)
// we may insert in both user and org_user tables
// therefore we need to query check quota for both user and org services
for _, srv := range []string{user.QuotaTargetSrv, org.QuotaTargetSrv} {
limitReached, errLimit := ls.QuotaService.QuotaReached(cmd.ReqContext, quota.TargetSrv(srv))
limitReached, errLimit := ls.QuotaService.CheckQuotaReached(ctx, quota.TargetSrv(srv), nil)
if errLimit != nil {
cmd.ReqContext.Logger.Warn("Error getting user quota.", "error", errLimit)
return login.ErrGettingUserQuota

View File

@@ -156,7 +156,13 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
func (api *API) Usage(ctx context.Context, scopeParams *quota.ScopeParameters) (*quota.Map, error) {
u := &quota.Map{}
if orgUsage, err := api.RuleStore.Count(ctx, scopeParams.OrgID); err != nil {
var orgID int64 = 0
if scopeParams != nil {
orgID = scopeParams.OrgID
}
if orgUsage, err := api.RuleStore.Count(ctx, orgID); err != nil {
return u, err
} else {
tag, err := quota.NewTag(models.QuotaTargetSrv, models.QuotaTarget, quota.OrgScope)

View File

@@ -420,7 +420,7 @@ func (ss *sqlStore) Count(ctx context.Context, scopeParams *quota.ScopeParameter
u.Set(tag, r.Count)
}
if scopeParams.OrgID != 0 {
if scopeParams != nil && scopeParams.OrgID != 0 {
if err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := fmt.Sprintf("SELECT COUNT(*) AS count FROM (SELECT user_id FROM org_user WHERE org_id=? AND user_id IN (SELECT id AS user_id FROM %s WHERE is_service_account=%s)) as subq",
ss.db.GetDialect().Quote("user"),
@@ -441,7 +441,7 @@ func (ss *sqlStore) Count(ctx context.Context, scopeParams *quota.ScopeParameter
}
}
if scopeParams.UserID != 0 {
if scopeParams != nil && scopeParams.UserID != 0 {
if err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
// should we exclude service accounts?
rawSQL := "SELECT COUNT(*) AS count FROM org_user WHERE user_id=?"