46 lines
1.2 KiB
Go
46 lines
1.2 KiB
Go
package identity
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"strings"
|
||
|
|
"unicode"
|
||
|
|
"unicode/utf8"
|
||
|
|
)
|
||
|
|
|
||
|
|
var ErrInvalidDisplayName = errors.New("invalid display name")
|
||
|
|
|
||
|
|
func ValidateDisplayName(name string) (string, error) {
|
||
|
|
name = strings.TrimSpace(name)
|
||
|
|
if !utf8.ValidString(name) || utf8.RuneCountInString(name) < 1 || utf8.RuneCountInString(name) > 80 {
|
||
|
|
return "", ErrInvalidDisplayName
|
||
|
|
}
|
||
|
|
for _, r := range name {
|
||
|
|
if unicode.IsControl(r) {
|
||
|
|
return "", ErrInvalidDisplayName
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return name, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// The principal comes from authenticated middleware. Callers cannot select another account.
|
||
|
|
func (r *Repository) UpdateDisplayName(ctx context.Context, principal Principal, name string) error {
|
||
|
|
name, err := ValidateDisplayName(name)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if principal.Issuer == "" || principal.Subject == "" {
|
||
|
|
return ErrAccessDenied
|
||
|
|
}
|
||
|
|
result, err := r.pool.Exec(ctx, `UPDATE user_account ua SET display_name=$3, updated_at=now()
|
||
|
|
FROM tenant t WHERE ua.tenant_id=t.id AND t.status='active' AND ua.status='active'
|
||
|
|
AND ua.oidc_issuer=$1 AND ua.oidc_subject=$2`, principal.Issuer, principal.Subject, name)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if result.RowsAffected() == 0 {
|
||
|
|
return ErrAccountNotFound
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|