forked from writefreely/writefreely
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unregisteredusers.go
144 lines (132 loc) · 4.08 KB
/
unregisteredusers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Copyright © 2018 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
* WriteFreely is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, included
* in the LICENSE file in this source code package.
*/
package writefreely
import (
"database/sql"
"encoding/json"
"github.com/writeas/impart"
"github.com/writeas/web-core/log"
"net/http"
)
func handleWebSignup(app *app, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
// Get params
var ur userRegistration
if reqJSON {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&ur)
if err != nil {
log.Error("Couldn't parse signup JSON request: %v\n", err)
return ErrBadJSON
}
} else {
err := r.ParseForm()
if err != nil {
log.Error("Couldn't parse signup form request: %v\n", err)
return ErrBadFormData
}
err = app.formDecoder.Decode(&ur, r.PostForm)
if err != nil {
log.Error("Couldn't decode signup form request: %v\n", err)
return ErrBadFormData
}
}
ur.Web = true
ur.Normalize = true
to := "/"
if ur.InviteCode != "" {
to = "/invite/" + ur.InviteCode
}
_, err := signupWithRegistration(app, ur, w, r)
if err != nil {
if err, ok := err.(impart.HTTPError); ok {
session, _ := app.sessionStore.Get(r, cookieName)
if session != nil {
session.AddFlash(err.Message)
session.Save(r, w)
return impart.HTTPError{http.StatusFound, to}
}
}
return err
}
return impart.HTTPError{http.StatusFound, to}
}
// { "username": "asdf" }
// result: { code: 204 }
func handleUsernameCheck(app *app, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
// Get params
var d struct {
Username string `json:"username"`
}
if reqJSON {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&d)
if err != nil {
log.Error("Couldn't decode username check: %v\n", err)
return ErrBadFormData
}
} else {
return impart.HTTPError{http.StatusNotAcceptable, "Must be JSON request"}
}
// Check if username is okay
finalUsername := getSlug(d.Username, "")
if finalUsername == "" {
errMsg := "Invalid username"
if d.Username != "" {
// Username was provided, but didn't convert into valid latin characters
errMsg += " - must have at least 2 letters or numbers"
}
return impart.HTTPError{http.StatusBadRequest, errMsg + "."}
}
if app.db.PostIDExists(finalUsername) {
return impart.HTTPError{http.StatusConflict, "Username is already taken."}
}
var un string
err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
switch {
case err == sql.ErrNoRows:
return impart.WriteSuccess(w, finalUsername, http.StatusOK)
case err != nil:
log.Error("Couldn't SELECT username: %v", err)
return impart.HTTPError{http.StatusInternalServerError, "We messed up."}
}
// Username was found, so it's taken
return impart.HTTPError{http.StatusConflict, "Username is already taken."}
}
func getValidUsername(app *app, reqName, prevName string) (string, *impart.HTTPError) {
// Check if username is okay
finalUsername := getSlug(reqName, "")
if finalUsername == "" {
errMsg := "Invalid username"
if reqName != "" {
// Username was provided, but didn't convert into valid latin characters
errMsg += " - must have at least 2 letters or numbers"
}
return "", &impart.HTTPError{http.StatusBadRequest, errMsg + "."}
}
if finalUsername == prevName {
return "", &impart.HTTPError{http.StatusNotModified, "Username unchanged."}
}
if app.db.PostIDExists(finalUsername) {
return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
}
var un string
err := app.db.QueryRow("SELECT username FROM users WHERE username = ?", finalUsername).Scan(&un)
switch {
case err == sql.ErrNoRows:
return finalUsername, nil
case err != nil:
log.Error("Couldn't SELECT username: %v", err)
return "", &impart.HTTPError{http.StatusInternalServerError, "We messed up."}
}
// Username was found, so it's taken
return "", &impart.HTTPError{http.StatusConflict, "Username is already taken."}
}