2023-09-20 16:55:49 +02:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
const AnonIssuer = "anon"
|
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
func WithAnonymousUser(funcs ...DefaultUserOptionFunc) DefaultUserOptionFunc {
|
|
|
|
return func(opts *DefaultUserOptions) {
|
|
|
|
opts.GetSubject = getAnonymousSubject
|
|
|
|
opts.GetPreferredUsername = getAnonymousPreferredUsername
|
|
|
|
opts.Issuer = AnonIssuer
|
2023-09-20 16:55:49 +02:00
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
for _, fn := range funcs {
|
|
|
|
fn(opts)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-20 16:55:49 +02:00
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
func getAnonymousSubject(r *http.Request) (string, error) {
|
|
|
|
uuid, err := uuid.NewUUID()
|
|
|
|
if err != nil {
|
|
|
|
return "", errors.Wrap(err, "could not generate uuid for anonymous user")
|
|
|
|
}
|
2023-09-20 16:55:49 +02:00
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
subject := fmt.Sprintf("%s-%s", AnonIssuer, uuid.String())
|
2023-09-20 16:55:49 +02:00
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
return subject, nil
|
|
|
|
}
|
2023-09-20 16:55:49 +02:00
|
|
|
|
2024-05-02 09:42:56 +02:00
|
|
|
func getAnonymousPreferredUsername(r *http.Request) (string, error) {
|
|
|
|
preferredUsername, err := generateRandomPreferredUsername(8)
|
|
|
|
if err != nil {
|
|
|
|
return "", errors.Wrap(err, "could not generate preferred username for anonymous user")
|
2023-09-20 16:55:49 +02:00
|
|
|
}
|
2024-05-02 09:42:56 +02:00
|
|
|
|
|
|
|
return preferredUsername, nil
|
2023-09-20 16:55:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func generateRandomPreferredUsername(size int) (string, error) {
|
|
|
|
var letters = []rune("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
|
|
max := big.NewInt(int64(len(letters)))
|
|
|
|
|
|
|
|
b := make([]rune, size)
|
|
|
|
for i := range b {
|
|
|
|
idx, err := rand.Int(rand.Reader, max)
|
|
|
|
if err != nil {
|
|
|
|
return "", errors.WithStack(err)
|
|
|
|
}
|
|
|
|
b[i] = letters[idx.Int64()]
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("Anon %s", string(b)), nil
|
|
|
|
}
|