Skip to content

Commit

Permalink
graph: Add some validation for username and email
Browse files Browse the repository at this point in the history
This copies the validation code from the accounts service, also fixing a
bug in the regex that allowed adding mail addresses with whitespace and
other problematic characters to the domain part of the mail address.

Partial fix for: owncloud#3247
  • Loading branch information
rhafer authored and labkode committed Mar 3, 2022
1 parent 56e486b commit 39dcae3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
4 changes: 2 additions & 2 deletions accounts/pkg/service/v0/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ func validateAccountEmail(serviceID string, a *accountsmsg.Account) error {
// We want to allow email addresses as usernames so they show up when using them in ACLs on storages that allow integration with our glauth LDAP service
// so we are adding a few restrictions from https://stackoverflow.com/questions/6949667/what-are-the-real-rules-for-linux-usernames-on-centos-6-and-rhel-6
// names should not start with numbers
var usernameRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*(@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)*$")
var usernameRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*(@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)*$")

func isValidUsername(e string) bool {
if len(e) < 1 && len(e) > 254 {
Expand All @@ -756,7 +756,7 @@ func isValidUsername(e string) bool {
}

// regex from https://www.w3.org/TR/2016/REC-html51-20161101/sec-forms.html#valid-e-mail-address
var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")

func isValidEmail(e string) bool {
if len(e) < 3 && len(e) > 254 {
Expand Down
44 changes: 43 additions & 1 deletion graph/pkg/service/v0/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package svc
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"regexp"

revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/go-chi/chi/v5"
Expand Down Expand Up @@ -56,7 +58,18 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
}

if isNilOrEmpty(u.DisplayName) || isNilOrEmpty(u.OnPremisesSamAccountName) || isNilOrEmpty(u.Mail) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Missing Required Attribute")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}

if !isValidUsername(*u.OnPremisesSamAccountName) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
fmt.Sprintf("username '%s' must be at least the local part of an email", *u.OnPremisesSamAccountName))
return
}
if !isValidEmail(*u.Mail) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
fmt.Sprintf("'%s' is not a valid email address", *u.Mail))
return
}

Expand Down Expand Up @@ -151,6 +164,13 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
return
}

mail := changes.GetMail()
if !isValidEmail(mail) {
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
fmt.Sprintf("'%s' is not a valid email address", mail))
return
}

u, err := g.identityBackend.UpdateUser(r.Context(), nameOrID, *changes)
if err != nil {
var errcode errorcode.Error
Expand All @@ -169,3 +189,25 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
func isNilOrEmpty(s *string) bool {
return s == nil || *s == ""
}

// We want to allow email addresses as usernames so they show up when using them in ACLs on storages that allow integration with our glauth LDAP service
// so we are adding a few restrictions from https://stackoverflow.com/questions/6949667/what-are-the-real-rules-for-linux-usernames-on-centos-6-and-rhel-6
// names should not start with numbers
var usernameRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]*(@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)*$")

func isValidUsername(e string) bool {
if len(e) < 1 && len(e) > 254 {
return false
}
return usernameRegex.MatchString(e)
}

// regex from https://www.w3.org/TR/2016/REC-html51-20161101/sec-forms.html#valid-e-mail-address
var emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")

func isValidEmail(e string) bool {
if len(e) < 3 && len(e) > 254 {
return false
}
return emailRegex.MatchString(e)
}

0 comments on commit 39dcae3

Please sign in to comment.