From 8191a52ce12680010af9380b193d8f8d5c4f9e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Fri, 12 Feb 2021 18:49:47 +0100 Subject: [PATCH] chore: make very first user have admin privileges --- mocks/user_service.go | 9 +++++++-- models/view/login.go | 5 +++-- repositories/repositories.go | 1 + repositories/user.go | 10 ++++++++++ routes/login.go | 11 ++++++++--- services/services.go | 3 ++- services/user.go | 7 ++++++- version.txt | 2 +- views/signup.tpl.html | 7 +++++++ 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/mocks/user_service.go b/mocks/user_service.go index c6bca7e..48eaf09 100644 --- a/mocks/user_service.go +++ b/mocks/user_service.go @@ -24,8 +24,13 @@ func (m *UserServiceMock) GetAll() ([]*models.User, error) { return args.Get(0).([]*models.User), args.Error(1) } -func (m *UserServiceMock) CreateOrGet(signup *models.Signup) (*models.User, bool, error) { - args := m.Called(signup) +func (m *UserServiceMock) Count() (int64, error) { + args := m.Called() + return int64(args.Int(0)), args.Error(1) +} + +func (m *UserServiceMock) CreateOrGet(signup *models.Signup, isAdmin bool) (*models.User, bool, error) { + args := m.Called(signup, isAdmin) return args.Get(0).(*models.User), args.Bool(1), args.Error(2) } diff --git a/models/view/login.go b/models/view/login.go index 1338790..57b62b0 100644 --- a/models/view/login.go +++ b/models/view/login.go @@ -1,8 +1,9 @@ package view type LoginViewModel struct { - Success string - Error string + Success string + Error string + TotalUsers int } func (s *LoginViewModel) WithSuccess(m string) *LoginViewModel { diff --git a/repositories/repositories.go b/repositories/repositories.go index 7eeb080..bc421b7 100644 --- a/repositories/repositories.go +++ b/repositories/repositories.go @@ -48,6 +48,7 @@ type IUserRepository interface { GetById(string) (*models.User, error) GetByApiKey(string) (*models.User, error) GetAll() ([]*models.User, error) + Count() (int64, error) InsertOrGet(*models.User) (*models.User, bool, error) Update(*models.User) (*models.User, error) UpdateField(*models.User, string, interface{}) (*models.User, error) diff --git a/repositories/user.go b/repositories/user.go index 43e080d..dc14695 100644 --- a/repositories/user.go +++ b/repositories/user.go @@ -40,6 +40,16 @@ func (r *UserRepository) GetAll() ([]*models.User, error) { return users, nil } +func (r *UserRepository) Count() (int64, error) { + var count int64 + if err := r.db. + Model(&models.User{}). + Count(&count).Error; err != nil { + return 0, err + } + return count, nil +} + func (r *UserRepository) InsertOrGet(user *models.User) (*models.User, bool, error) { result := r.db.FirstOrCreate(user, &models.User{ID: user.ID}) if err := result.Error; err != nil { diff --git a/routes/login.go b/routes/login.go index a1ff615..9c140cb 100644 --- a/routes/login.go +++ b/routes/login.go @@ -150,7 +150,9 @@ func (h *LoginHandler) PostSignup(w http.ResponseWriter, r *http.Request) { return } - _, created, err := h.userSrvc.CreateOrGet(&signup) + numUsers, _ := h.userSrvc.Count() + + _, created, err := h.userSrvc.CreateOrGet(&signup, numUsers == 0) if err != nil { w.WriteHeader(http.StatusInternalServerError) templates[conf.SignupTemplate].Execute(w, h.buildViewModel(r).WithError("failed to create new user")) @@ -166,8 +168,11 @@ func (h *LoginHandler) PostSignup(w http.ResponseWriter, r *http.Request) { } func (h *LoginHandler) buildViewModel(r *http.Request) *view.LoginViewModel { + numUsers, _ := h.userSrvc.Count() + return &view.LoginViewModel{ - Success: r.URL.Query().Get("success"), - Error: r.URL.Query().Get("error"), + Success: r.URL.Query().Get("success"), + Error: r.URL.Query().Get("error"), + TotalUsers: int(numUsers), } } diff --git a/services/services.go b/services/services.go index 38d9941..45670e8 100644 --- a/services/services.go +++ b/services/services.go @@ -63,7 +63,8 @@ type IUserService interface { GetUserById(string) (*models.User, error) GetUserByKey(string) (*models.User, error) GetAll() ([]*models.User, error) - CreateOrGet(*models.Signup) (*models.User, bool, error) + Count() (int64, error) + CreateOrGet(*models.Signup, bool) (*models.User, bool, error) Update(*models.User) (*models.User, error) Delete(*models.User) error ResetApiKey(*models.User) (*models.User, error) diff --git a/services/user.go b/services/user.go index e7f3f9f..072767b 100644 --- a/services/user.go +++ b/services/user.go @@ -56,11 +56,16 @@ func (srv *UserService) GetAll() ([]*models.User, error) { return srv.repository.GetAll() } -func (srv *UserService) CreateOrGet(signup *models.Signup) (*models.User, bool, error) { +func (srv *UserService) Count() (int64, error) { + return srv.repository.Count() +} + +func (srv *UserService) CreateOrGet(signup *models.Signup, isAdmin bool) (*models.User, bool, error) { u := &models.User{ ID: signup.Username, ApiKey: uuid.NewV4().String(), Password: signup.Password, + IsAdmin: isAdmin, } if hash, err := utils.HashBcrypt(u.Password, srv.Config.Security.PasswordSalt); err != nil { diff --git a/version.txt b/version.txt index fa994bd..f4ce203 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.23.6 \ No newline at end of file +1.23.7 \ No newline at end of file diff --git a/views/signup.tpl.html b/views/signup.tpl.html index 0d51b35..084b383 100644 --- a/views/signup.tpl.html +++ b/views/signup.tpl.html @@ -49,6 +49,13 @@ type="password" id="password_repeat" name="password_repeat" placeholder="Repeat your password" minlength="6" required> + + {{ if eq .TotalUsers 0 }} +

+ ⚠️ Please note: Since there are no users registered in the system, yet, the first user will have administrative privileges, while additional users won't. +

+ {{ end }} +