Compare commits
2 Commits
41c0a47f54
...
8f7defdb8a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f7defdb8a | ||
|
|
0c190efda4 |
24
README.md
24
README.md
@@ -85,6 +85,30 @@ auth:
|
||||
go run ./cmd/qfs -migrate
|
||||
```
|
||||
|
||||
### Минимальные права БД для пользователя квотаций
|
||||
|
||||
Если нужен пользователь, который может создавать/редактировать квотации, но не может управлять ценами:
|
||||
|
||||
```sql
|
||||
DROP USER IF EXISTS 'quote_user'@'%';
|
||||
CREATE USER 'quote_user'@'%' IDENTIFIED BY 'StrongPassword!';
|
||||
|
||||
-- чтение данных для расчета/просмотра
|
||||
GRANT SELECT ON RFQ_LOG.lot TO 'quote_user'@'%';
|
||||
GRANT SELECT ON RFQ_LOG.qt_lot_metadata TO 'quote_user'@'%';
|
||||
GRANT SELECT ON RFQ_LOG.qt_pricelists TO 'quote_user'@'%';
|
||||
GRANT SELECT ON RFQ_LOG.qt_pricelist_items TO 'quote_user'@'%';
|
||||
GRANT SELECT ON RFQ_LOG.qt_users TO 'quote_user'@'%';
|
||||
|
||||
-- работа с квотациями
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON RFQ_LOG.qt_configurations TO 'quote_user'@'%';
|
||||
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
Важно: этот вариант не ограничивает редактирование только своими записями в `qt_configurations`.
|
||||
Если пересоздавать пользователя нельзя, используйте `SHOW GRANTS FOR 'quote_user'@'%';` и сделайте точечные `REVOKE`.
|
||||
|
||||
### 4. Импорт метаданных компонентов
|
||||
|
||||
```bash
|
||||
|
||||
@@ -484,6 +484,9 @@ func (s *Service) pushConfigurationCreate(change *localdb.PendingChange) error {
|
||||
|
||||
// Create repository
|
||||
configRepo := repository.NewConfigurationRepository(mariaDB)
|
||||
if err := s.ensureConfigurationOwner(mariaDB, &cfg); err != nil {
|
||||
return fmt.Errorf("resolve configuration owner: %w", err)
|
||||
}
|
||||
|
||||
// Create on server
|
||||
if err := configRepo.Create(&cfg); err != nil {
|
||||
@@ -536,6 +539,9 @@ func (s *Service) pushConfigurationUpdate(change *localdb.PendingChange) error {
|
||||
|
||||
// Create repository
|
||||
configRepo := repository.NewConfigurationRepository(mariaDB)
|
||||
if err := s.ensureConfigurationOwner(mariaDB, &cfg); err != nil {
|
||||
return fmt.Errorf("resolve configuration owner: %w", err)
|
||||
}
|
||||
|
||||
// Ensure we have a server ID before updating
|
||||
// If the payload doesn't have ID, get it from local configuration
|
||||
@@ -585,6 +591,32 @@ func (s *Service) pushConfigurationUpdate(change *localdb.PendingChange) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) ensureConfigurationOwner(mariaDB *gorm.DB, cfg *models.Configuration) error {
|
||||
if cfg == nil {
|
||||
return fmt.Errorf("configuration is nil")
|
||||
}
|
||||
|
||||
ownerUsername := cfg.OwnerUsername
|
||||
if ownerUsername == "" {
|
||||
ownerUsername = s.localDB.GetDBUser()
|
||||
cfg.OwnerUsername = ownerUsername
|
||||
}
|
||||
if ownerUsername == "" {
|
||||
return fmt.Errorf("owner username is empty")
|
||||
}
|
||||
|
||||
userID, err := models.EnsureDBUser(mariaDB, ownerUsername)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if userID == 0 {
|
||||
return fmt.Errorf("resolved user ID is 0 for owner %q", ownerUsername)
|
||||
}
|
||||
|
||||
cfg.UserID = userID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) pushConfigurationRollback(change *localdb.PendingChange) error {
|
||||
// Last-write-wins for now: rollback is pushed as an update with rollback metadata.
|
||||
return s.pushConfigurationUpdate(change)
|
||||
|
||||
Reference in New Issue
Block a user