Spaces and underscores in usernames now don't make a difference

This commit is contained in:
Howl 2016-10-16 18:52:34 +02:00
parent 2e1713db49
commit 325df61d96
3 changed files with 23 additions and 15 deletions

View File

@ -40,23 +40,23 @@ func genUser(c *gin.Context, db *sqlx.DB) (string, string) {
switch { switch {
// We know for sure that it's an username. // We know for sure that it's an username.
case c.Query("type") == "string": case c.Query("type") == "string":
whereClause = "users.username = ?" whereClause = "users.username_safe = ?"
p = c.Query("u") p = common.SafeUsername(c.Query("u"))
// It could be an user ID, so we look for an user with that username first. // It could be an user ID, so we look for an user with that username first.
case err == nil: case err == nil:
err = db.QueryRow("SELECT id FROM users WHERE id = ? LIMIT 1", s).Scan(&p) err = db.QueryRow("SELECT id FROM users WHERE id = ? LIMIT 1", s).Scan(&p)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
// If no user with that userID were found, assume username. // If no user with that userID were found, assume username.
p = c.Query("u") whereClause = "users.username_safe = ?"
whereClause = "users.username = ?" p = common.SafeUsername(c.Query("u"))
} else { } else {
// An user with that userID was found. Thus it's an userID. // An user with that userID was found. Thus it's an userID.
whereClause = "users.id = ?" whereClause = "users.id = ?"
} }
// u contains letters, so it's an username. // u contains letters, so it's an username.
default: default:
p = c.Query("u") whereClause = "users.username_safe = ?"
whereClause = "users.username = ?" p = common.SafeUsername(c.Query("u"))
} }
return whereClause, p return whereClause, p
} }

View File

@ -59,7 +59,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
if data.UserID != 0 { if data.UserID != 0 {
q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID) q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID)
} else { } else {
q = md.DB.QueryRow(base+"WHERE username = ? LIMIT 1", data.Username) q = md.DB.QueryRow(base+"WHERE username = ? LIMIT 1", common.SafeUsername(data.Username))
} }
var ( var (

View File

@ -76,14 +76,14 @@ func userPutsMulti(md common.MethodData) common.CodeMessager {
// query composition // query composition
wh := common. wh := common.
Where("users.username = ?", md.Query("nname")). Where("users.username_safe = ?", common.SafeUsername(md.Query("nname"))).
Where("users.id = ?", md.Query("iid")). Where("users.id = ?", md.Query("iid")).
Where("users.privileges = ?", md.Query("privileges")). Where("users.privileges = ?", md.Query("privileges")).
Where("users.privileges & ? > 0", md.Query("has_privileges")). Where("users.privileges & ? > 0", md.Query("has_privileges")).
Where("users_stats.country = ?", md.Query("country")). Where("users_stats.country = ?", md.Query("country")).
Where("users_stats.username_aka = ?", md.Query("name_aka")). Where("users_stats.username_aka = ?", md.Query("name_aka")).
In("users.id", q["ids"]...). In("users.id", q["ids"]...).
In("users.username", q["names"]...). In("users.username_safe", safeUsernameBulk(q["names"])...).
In("users_stats.username_aka", q["names_aka"]...). In("users_stats.username_aka", q["names_aka"]...).
In("users_stats.country", q["countries"]...) In("users_stats.country", q["countries"]...)
query := "" + query := "" +
@ -128,6 +128,13 @@ func UserSelfGET(md common.MethodData) common.CodeMessager {
return UsersGET(md) return UsersGET(md)
} }
func safeUsernameBulk(us []string) []string {
for i, u := range us {
us[i] = common.SafeUsername(u)
}
return us
}
type whatIDResponse struct { type whatIDResponse struct {
common.ResponseBase common.ResponseBase
ID int `json:"id"` ID int `json:"id"`
@ -139,7 +146,7 @@ func UserWhatsTheIDGET(md common.MethodData) common.CodeMessager {
r whatIDResponse r whatIDResponse
privileges uint64 privileges uint64
) )
err := md.DB.QueryRow("SELECT id, privileges FROM users WHERE username = ? LIMIT 1", md.Query("name")).Scan(&r.ID, &privileges) err := md.DB.QueryRow("SELECT id, privileges FROM users WHERE username_safe = ? LIMIT 1", common.SafeUsername(md.Query("name"))).Scan(&r.ID, &privileges)
if err != nil || ((privileges&uint64(common.UserPrivilegePublic)) == 0 && if err != nil || ((privileges&uint64(common.UserPrivilegePublic)) == 0 &&
(md.User.UserPrivileges&common.AdminPrivilegeManageUsers == 0)) { (md.User.UserPrivileges&common.AdminPrivilegeManageUsers == 0)) {
return common.SimpleResponse(404, "That user could not be found!") return common.SimpleResponse(404, "That user could not be found!")
@ -323,7 +330,7 @@ func whereClauseUser(md common.MethodData, tableName string) (*common.CodeMessag
} }
return nil, tableName + ".id = ?", id return nil, tableName + ".id = ?", id
case md.Query("name") != "": case md.Query("name") != "":
return nil, tableName + ".username = ?", md.Query("name") return nil, tableName + ".username_safe = ?", common.SafeUsername(md.Query("name"))
} }
a := common.SimpleResponse(400, "you need to pass either querystring parameters name or id") a := common.SimpleResponse(400, "you need to pass either querystring parameters name or id")
return &a, "", nil return &a, "", nil
@ -341,16 +348,18 @@ type lookupUser struct {
// UserLookupGET does a quick lookup of users beginning with the passed // UserLookupGET does a quick lookup of users beginning with the passed
// querystring value name. // querystring value name.
func UserLookupGET(md common.MethodData) common.CodeMessager { func UserLookupGET(md common.MethodData) common.CodeMessager {
name := strings.NewReplacer( name := common.SafeUsername(md.Query("name"))
name = strings.NewReplacer(
"%", "\\%", "%", "\\%",
"_", "\\_", "_", "\\_",
"\\", "\\\\", "\\", "\\\\",
).Replace(md.Query("name")) ).Replace(name)
if name == "" { if name == "" {
return common.SimpleResponse(400, "please provide an username to start searching") return common.SimpleResponse(400, "please provide an username to start searching")
} }
name = "%" + name + "%" name = "%" + name + "%"
rows, err := md.DB.Query("SELECT users.id, users.username FROM users WHERE username LIKE ? AND "+
rows, err := md.DB.Query("SELECT users.id, users.username FROM users WHERE username_safe LIKE ? AND "+
md.User.OnlyUserPublic(true)+" LIMIT 25", name) md.User.OnlyUserPublic(true)+" LIMIT 25", name)
if err != nil { if err != nil {
md.Err(err) md.Err(err)
@ -358,7 +367,6 @@ func UserLookupGET(md common.MethodData) common.CodeMessager {
} }
var r userLookupResponse var r userLookupResponse
for rows.Next() { for rows.Next() {
var l lookupUser var l lookupUser
err := rows.Scan(&l.ID, &l.Username) err := rows.Scan(&l.ID, &l.Username)