ultisuite-backend/internal/provision/authentik.go
R3D347HR4Y 7143a36c19
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
feat(mail): integrate Stalwart hosted mail and migration features
- Added configuration options for Stalwart hosted mail in .env.example.
- Updated Docker Compose to include Stalwart service with health checks.
- Introduced new API endpoints for managing mail domains and migration projects.
- Enhanced Authentik blueprints for user enrollment and post-migration security.
- Updated OAuth handling for Google and Microsoft migration processes.
- Improved error handling and response structures in the mail API.
- Added integration tests for email claiming and migration workflows.
2026-06-13 12:47:08 +02:00

76 lines
1.7 KiB
Go

package provision
import (
"encoding/json"
"net/http"
"strconv"
"strings"
)
func authorizeProvision(r *http.Request, secret string) bool {
if secret == "" {
return false
}
if r.Header.Get("X-Provision-Secret") == secret {
return true
}
if r.URL.Query().Get("secret") == secret {
return true
}
return false
}
type authentikWebhookPayload struct {
Email string `json:"email"`
Username string `json:"username"`
Name string `json:"name"`
Password string `json:"password"`
ExternalID string `json:"external_id"`
Sub string `json:"sub"`
User struct {
Email string `json:"email"`
Username string `json:"username"`
Name string `json:"name"`
UUID string `json:"uuid"`
PK int `json:"pk"`
} `json:"user"`
}
func decodeProvisionBody(r *http.Request) (provisionUserRequest, error) {
var ak authentikWebhookPayload
if err := json.NewDecoder(r.Body).Decode(&ak); err != nil {
return provisionUserRequest{}, err
}
req := provisionUserRequest{
Email: firstNonEmpty(ak.Email, ak.User.Email),
Username: firstNonEmpty(ak.Username, ak.User.Username),
Name: firstNonEmpty(ak.Name, ak.User.Name),
Password: ak.Password,
ExternalID: firstNonEmpty(ak.ExternalID, ak.Sub, ak.User.UUID),
}
if req.ExternalID == "" && ak.User.PK > 0 {
req.ExternalID = strconv.Itoa(ak.User.PK)
}
normalizeProvisionRequest(&req)
return req, nil
}
func normalizeProvisionRequest(dst *provisionUserRequest) {
if dst.Email == "" {
dst.Email = strings.ToLower(strings.TrimSpace(dst.Username))
}
if dst.Name == "" {
dst.Name = dst.Email
}
}
func firstNonEmpty(values ...string) string {
for _, v := range values {
if strings.TrimSpace(v) != "" {
return strings.TrimSpace(v)
}
}
return ""
}