chore: add ansible deploy simple logic, upgrade admin auth logic and docs
ci-agent / build (push) Failing after 1m55s
ci-agent / build (push) Failing after 1m55s
This commit is contained in:
@@ -21,6 +21,7 @@ func New(db *sql.DB) *Repository {
|
||||
}
|
||||
|
||||
var ErrNotFound = errors.New("not found")
|
||||
var ErrAccountInactive = errors.New("account is not activated")
|
||||
|
||||
// Init creates the tokens table if it does not exist.
|
||||
func (r *Repository) Init() error {
|
||||
@@ -29,6 +30,7 @@ func (r *Repository) Init() error {
|
||||
}
|
||||
|
||||
// CreateToken inserts a new user record with hashed password and generated token.
|
||||
// New users are created with is_active=false by default.
|
||||
func (r *Repository) CreateToken(tc TokenCreate) (string, error) {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(tc.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
@@ -41,10 +43,10 @@ func (r *Repository) CreateToken(tc TokenCreate) (string, error) {
|
||||
}
|
||||
|
||||
result, err := r.DB.Exec(
|
||||
`INSERT INTO tokens (name, last_name, login, password, token, permission_view, permission_manage_agent, permission_admin)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
`INSERT INTO tokens (name, last_name, login, password, token, permission_view, permission_manage_agent, permission_admin, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
tc.Name, tc.LastName, tc.Login, string(hashed), token,
|
||||
tc.PermissionView, tc.PermissionManage, tc.PermissionAdmin,
|
||||
tc.PermissionView, tc.PermissionManage, tc.PermissionAdmin, false,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -63,11 +65,11 @@ func (r *Repository) Login(login, password string) (*LoginResponse, error) {
|
||||
var hashedPassword string
|
||||
|
||||
err := r.DB.QueryRow(
|
||||
`SELECT id, name, last_name, login, password, token, permission_view, permission_manage_agent, permission_admin
|
||||
`SELECT id, name, last_name, login, password, token, permission_view, permission_manage_agent, permission_admin, is_active
|
||||
FROM tokens WHERE login = ?`,
|
||||
login,
|
||||
).Scan(&t.ID, &t.Name, &t.LastName, &t.Login, &hashedPassword, &t.Token,
|
||||
&t.PermissionView, &t.PermissionManage, &t.PermissionAdmin)
|
||||
&t.PermissionView, &t.PermissionManage, &t.PermissionAdmin, &t.IsActive)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
@@ -80,6 +82,10 @@ func (r *Repository) Login(login, password string) (*LoginResponse, error) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
if !t.IsActive {
|
||||
return nil, ErrAccountInactive
|
||||
}
|
||||
|
||||
// Generate new token on each login
|
||||
newToken, err := utils.RandomToken()
|
||||
if err != nil {
|
||||
@@ -99,6 +105,7 @@ func (r *Repository) Login(login, password string) (*LoginResponse, error) {
|
||||
PermissionView: t.PermissionView,
|
||||
PermissionManage: t.PermissionManage,
|
||||
PermissionAdmin: t.PermissionAdmin,
|
||||
IsActive: t.IsActive,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -244,3 +251,207 @@ func (r *Repository) MarkRegistrationTokenUsed(token string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ActivateToken activates a user by token value.
|
||||
func (r *Repository) ActivateToken(token string) error {
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET is_active = 1 WHERE token = ?`,
|
||||
token,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeactivateToken deactivates a user by token value.
|
||||
func (r *Repository) DeactivateToken(token string) error {
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET is_active = 0 WHERE token = ?`,
|
||||
token,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ActivateUserByLogin activates a user by login.
|
||||
func (r *Repository) ActivateUserByLogin(login string) error {
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET is_active = 1 WHERE login = ?`,
|
||||
login,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeactivateUserByLogin deactivates a user by login.
|
||||
func (r *Repository) DeactivateUserByLogin(login string) error {
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET is_active = 0 WHERE login = ?`,
|
||||
login,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListInactiveTokens returns all users that are not activated.
|
||||
func (r *Repository) ListInactiveTokens() ([]Tokens, error) {
|
||||
rows, err := r.DB.Query(
|
||||
`SELECT id, name, last_name, login, token, permission_view, permission_manage_agent, permission_admin, is_active
|
||||
FROM tokens WHERE is_active = 0`,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var tokens []Tokens
|
||||
for rows.Next() {
|
||||
var t Tokens
|
||||
if err := rows.Scan(&t.ID, &t.Name, &t.LastName, &t.Login, &t.Token,
|
||||
&t.PermissionView, &t.PermissionManage, &t.PermissionAdmin, &t.IsActive); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokens = append(tokens, t)
|
||||
}
|
||||
return tokens, rows.Err()
|
||||
}
|
||||
|
||||
// GetTokenByLogin retrieves a user by login.
|
||||
func (r *Repository) GetTokenByLogin(login string) (*Tokens, error) {
|
||||
var t Tokens
|
||||
err := r.DB.QueryRow(
|
||||
`SELECT id, name, last_name, login, token, permission_view, permission_manage_agent, permission_admin, is_active
|
||||
FROM tokens WHERE login = ?`,
|
||||
login,
|
||||
).Scan(&t.ID, &t.Name, &t.LastName, &t.Login, &t.Token,
|
||||
&t.PermissionView, &t.PermissionManage, &t.PermissionAdmin, &t.IsActive)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
// UpdateToken updates name and last_name for a user by login.
|
||||
func (r *Repository) UpdateToken(login string, update TokenUpdate) error {
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET name = ?, last_name = ? WHERE login = ?`,
|
||||
update.Name, update.LastName, login,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePermissions updates permissions and is_active for a user by login.
|
||||
func (r *Repository) UpdatePermissions(login string, update TokenUpdatePermissions) error {
|
||||
user, err := r.GetTokenByLogin(login)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use existing values if not provided
|
||||
newView := user.PermissionView
|
||||
newManage := user.PermissionManage
|
||||
newAdmin := user.PermissionAdmin
|
||||
newActive := user.IsActive
|
||||
|
||||
if update.PermissionView != nil {
|
||||
newView = *update.PermissionView
|
||||
}
|
||||
if update.PermissionManage != nil {
|
||||
newManage = *update.PermissionManage
|
||||
}
|
||||
if update.PermissionAdmin != nil {
|
||||
newAdmin = *update.PermissionAdmin
|
||||
}
|
||||
if update.IsActive != nil {
|
||||
newActive = *update.IsActive
|
||||
}
|
||||
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET permission_view = ?, permission_manage_agent = ?, permission_admin = ?, is_active = ? WHERE login = ?`,
|
||||
newView, newManage, newAdmin, newActive, login,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePassword updates the password for a user by login.
|
||||
func (r *Repository) UpdatePassword(login string, newPassword string) error {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result, err := r.DB.Exec(
|
||||
`UPDATE tokens SET password = ? WHERE login = ?`,
|
||||
string(hashed), login,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if affected == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user