mirror of https://github.com/grafana/grafana
Auth: Case insensitive ids duplicate usagestats (#50724)
* WIP * update for prometheus * usagestats: tests pass for user duplicate entries * metrics: added duplicate user entries * usagestats: adds metrics gauge for duplicate users * usagestats: skip test for mysql * sql in oneplace * only use prometheus register to not panic * usagestats: RegisterMetricsFunc with loginstats * fix: remove unused commited code * refactor: move test to authinfoservice * Update pkg/models/stats.go Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> * removed prometheus metrics, due to sql cpu requirement * Added: has_duplicate_user_entries and fix tests * remove unused test * fix: empty else statement removal * missing argument to authinfoservice Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>pull/51246/head
parent
5ad3d10016
commit
421f7a999a
@ -0,0 +1,57 @@ |
|||||||
|
package database |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore" |
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore/db" |
||||||
|
) |
||||||
|
|
||||||
|
type loginStats struct { |
||||||
|
DuplicateUserEntries int `xorm:"duplicate_user_entries"` |
||||||
|
} |
||||||
|
|
||||||
|
func (s *AuthInfoStore) GetLoginStats(ctx context.Context) (loginStats, error) { |
||||||
|
var stats loginStats |
||||||
|
outerErr := s.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error { |
||||||
|
rawSQL := `SELECT COUNT(*) as duplicate_user_entries FROM (` + s.duplicateUserEntriesSQL(ctx) + `)` |
||||||
|
_, err := dbSession.SQL(rawSQL).Get(&stats) |
||||||
|
return err |
||||||
|
}) |
||||||
|
if outerErr != nil { |
||||||
|
return stats, outerErr |
||||||
|
} |
||||||
|
return stats, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (s *AuthInfoStore) CollectLoginStats(ctx context.Context) (map[string]interface{}, error) { |
||||||
|
m := map[string]interface{}{} |
||||||
|
|
||||||
|
loginStats, err := s.GetLoginStats(ctx) |
||||||
|
if err != nil { |
||||||
|
s.logger.Error("Failed to get login stats", "error", err) |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
m["stats.users.duplicate_user_entries"] = loginStats.DuplicateUserEntries |
||||||
|
if loginStats.DuplicateUserEntries > 0 { |
||||||
|
m["stats.users.has_duplicate_user_entries"] = 1 |
||||||
|
} else { |
||||||
|
m["stats.users.has_duplicate_user_entries"] = 0 |
||||||
|
} |
||||||
|
return m, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (s *AuthInfoStore) duplicateUserEntriesSQL(ctx context.Context) string { |
||||||
|
userDialect := db.DB.GetDialect(s.sqlStore).Quote("user") |
||||||
|
// this query counts how many users have the same login or email.
|
||||||
|
// which might be confusing, but gives a good indication
|
||||||
|
// we want this query to not require too much cpu
|
||||||
|
sqlQuery := `SELECT |
||||||
|
(SELECT login from ` + userDialect + ` WHERE (LOWER(login) = LOWER(u.login)) AND (login != u.login)) AS dup_login, |
||||||
|
(SELECT email from ` + userDialect + ` WHERE (LOWER(email) = LOWER(u.email)) AND (email != u.email)) AS dup_email |
||||||
|
FROM ` + userDialect + ` AS u |
||||||
|
WHERE (dup_login IS NOT NULL OR dup_email IS NOT NULL) |
||||||
|
` |
||||||
|
return sqlQuery |
||||||
|
} |
||||||
Loading…
Reference in new issue