1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00

Normalize local usernames using PRECIS

This patch implements local username normalization using PRECIS
(https://tools.ietf.org/html/rfc7564,
https://tools.ietf.org/html/rfc7613)

It makes chasquid accept local email and authentication regardless of
the case. It covers both userdb and aliases.

Note that non-local usernames remain untouched.
This commit is contained in:
Alberto Bertogli
2016-10-09 13:18:19 +01:00
parent 220b5d20ff
commit ad25706d72
8 changed files with 148 additions and 43 deletions

View File

@@ -0,0 +1,31 @@
// Package normalize contains functions to normalize usernames and addresses.
package normalize
import (
"blitiri.com.ar/go/chasquid/internal/envelope"
"golang.org/x/text/secure/precis"
)
// User normalices an username using PRECIS.
// On error, it will also return the original username to simplify callers.
func User(user string) (string, error) {
norm, err := precis.UsernameCaseMapped.String(user)
if err != nil {
return user, err
}
return norm, nil
}
// Name normalices an email address using PRECIS.
// On error, it will also return the original address to simplify callers.
func Addr(addr string) (string, error) {
user, domain := envelope.Split(addr)
user, err := User(user)
if err != nil {
return addr, err
}
return user + "@" + domain, nil
}

View File

@@ -0,0 +1,64 @@
package normalize
import "testing"
func TestUser(t *testing.T) {
valid := []struct{ user, norm string }{
{"ÑAndÚ", "ñandú"},
{"Pingüino", "pingüino"},
}
for _, c := range valid {
nu, err := User(c.user)
if nu != c.norm {
t.Errorf("%q normalized to %q, expected %q", c.user, nu, c.norm)
}
if err != nil {
t.Errorf("%q error: %v", c.user, err)
}
}
invalid := []string{
"á é", "a\te", "x ", "x\xa0y", "x\x85y", "x\vy", "x\fy", "x\ry",
"henry\u2163", "\u265a", "\u00b9",
}
for _, u := range invalid {
nu, err := User(u)
if err == nil {
t.Errorf("expected User(%+q) to fail, but did not", u)
}
if nu != u {
t.Errorf("%+q failed norm, but returned %+q", u, nu)
}
}
}
func TestAddr(t *testing.T) {
valid := []struct{ user, norm string }{
{"ÑAndÚ@pampa", "ñandú@pampa"},
{"Pingüino@patagonia", "pingüino@patagonia"},
}
for _, c := range valid {
nu, err := Addr(c.user)
if nu != c.norm {
t.Errorf("%q normalized to %q, expected %q", c.user, nu, c.norm)
}
if err != nil {
t.Errorf("%q error: %v", c.user, err)
}
}
invalid := []string{
"á é@i", "henry\u2163@throne",
}
for _, u := range invalid {
nu, err := Addr(u)
if err == nil {
t.Errorf("expected Addr(%+q) to fail, but did not", u)
}
if nu != u {
t.Errorf("%+q failed norm, but returned %+q", u, nu)
}
}
}