enforce CSRF token usage by the same IP for which it was issued
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
853086b942
commit
aaf940edab
8 changed files with 457 additions and 186 deletions
|
@ -49,16 +49,19 @@ type jwtTokenClaims struct {
|
|||
Username string
|
||||
Permissions []string
|
||||
Signature string
|
||||
Audience string
|
||||
Audience []string
|
||||
APIKeyID string
|
||||
MustSetTwoFactorAuth bool
|
||||
RequiredTwoFactorProtocols []string
|
||||
}
|
||||
|
||||
func (c *jwtTokenClaims) hasUserAudience() bool {
|
||||
if c.Audience == tokenAudienceWebClient || c.Audience == tokenAudienceAPIUser {
|
||||
return true
|
||||
for _, audience := range c.Audience {
|
||||
if audience == tokenAudienceWebClient || audience == tokenAudienceAPIUser {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -97,9 +100,7 @@ func (c *jwtTokenClaims) Decode(token map[string]interface{}) {
|
|||
|
||||
switch v := audience.(type) {
|
||||
case []string:
|
||||
if len(v) > 0 {
|
||||
c.Audience = v[0]
|
||||
}
|
||||
c.Audience = v
|
||||
}
|
||||
|
||||
if val, ok := token[claimAPIKey]; ok {
|
||||
|
@ -163,10 +164,10 @@ func (c *jwtTokenClaims) createToken(tokenAuth *jwtauth.JWTAuth, audience tokenA
|
|||
claims := c.asMap()
|
||||
now := time.Now().UTC()
|
||||
|
||||
claims[jwt.JwtIDKey] = fmt.Sprintf("%s%s", xid.New().String(), ip)
|
||||
claims[jwt.JwtIDKey] = xid.New().String()
|
||||
claims[jwt.NotBeforeKey] = now.Add(-30 * time.Second)
|
||||
claims[jwt.ExpirationKey] = now.Add(tokenDuration)
|
||||
claims[jwt.AudienceKey] = audience
|
||||
claims[jwt.AudienceKey] = []string{audience, ip}
|
||||
|
||||
return tokenAuth.Encode(claims)
|
||||
}
|
||||
|
@ -299,14 +300,14 @@ func getAdminFromToken(r *http.Request) *dataprovider.Admin {
|
|||
return admin
|
||||
}
|
||||
|
||||
func createCSRFToken() string {
|
||||
func createCSRFToken(ip string) string {
|
||||
claims := make(map[string]interface{})
|
||||
now := time.Now().UTC()
|
||||
|
||||
claims[jwt.JwtIDKey] = xid.New().String()
|
||||
claims[jwt.NotBeforeKey] = now.Add(-30 * time.Second)
|
||||
claims[jwt.ExpirationKey] = now.Add(csrfTokenDuration)
|
||||
claims[jwt.AudienceKey] = tokenAudienceCSRF
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceCSRF, ip}
|
||||
|
||||
_, tokenString, err := csrfTokenAuth.Encode(claims)
|
||||
if err != nil {
|
||||
|
@ -316,7 +317,7 @@ func createCSRFToken() string {
|
|||
return tokenString
|
||||
}
|
||||
|
||||
func verifyCSRFToken(tokenString string) error {
|
||||
func verifyCSRFToken(tokenString, ip string) error {
|
||||
token, err := jwtauth.VerifyToken(csrfTokenAuth, tokenString)
|
||||
if err != nil || token == nil {
|
||||
logger.Debug(logSender, "", "error validating CSRF token %#v: %v", tokenString, err)
|
||||
|
@ -328,5 +329,10 @@ func verifyCSRFToken(tokenString string) error {
|
|||
return errors.New("the form token is not valid")
|
||||
}
|
||||
|
||||
if !util.IsStringInSlice(ip, token.Audience()) {
|
||||
logger.Debug(logSender, "", "error validating CSRF token IP audience")
|
||||
return errors.New("the form token is not valid")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -633,7 +633,7 @@ func TestUpdateWebAdminInvalidClaims(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
form := make(url.Values)
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken(""))
|
||||
form.Set("status", "1")
|
||||
req, _ := http.NewRequest(http.MethodPost, path.Join(webAdminPath, "admin"), bytes.NewBuffer([]byte(form.Encode())))
|
||||
rctx := chi.NewRouteContext()
|
||||
|
@ -688,7 +688,7 @@ func TestRetentionInvalidTokenClaims(t *testing.T) {
|
|||
|
||||
func TestCSRFToken(t *testing.T) {
|
||||
// invalid token
|
||||
err := verifyCSRFToken("token")
|
||||
err := verifyCSRFToken("token", "")
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "unable to verify form token")
|
||||
}
|
||||
|
@ -699,15 +699,29 @@ func TestCSRFToken(t *testing.T) {
|
|||
claims[jwt.JwtIDKey] = xid.New().String()
|
||||
claims[jwt.NotBeforeKey] = now.Add(-30 * time.Second)
|
||||
claims[jwt.ExpirationKey] = now.Add(tokenDuration)
|
||||
claims[jwt.AudienceKey] = tokenAudienceAPI
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceAPI}
|
||||
|
||||
_, tokenString, err := csrfTokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
err = verifyCSRFToken(tokenString)
|
||||
err = verifyCSRFToken(tokenString, "")
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "form token is not valid")
|
||||
}
|
||||
|
||||
// bad IP
|
||||
tokenString = createCSRFToken("127.1.1.1")
|
||||
err = verifyCSRFToken(tokenString, "127.1.1.2")
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "form token is not valid")
|
||||
}
|
||||
|
||||
claims[jwt.JwtIDKey] = xid.New().String()
|
||||
claims[jwt.NotBeforeKey] = now.Add(-30 * time.Second)
|
||||
claims[jwt.ExpirationKey] = now.Add(tokenDuration)
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceAPI}
|
||||
_, tokenString, err = csrfTokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := GetHTTPRouter(Binding{
|
||||
Address: "",
|
||||
Port: 8080,
|
||||
|
@ -722,6 +736,15 @@ func TestCSRFToken(t *testing.T) {
|
|||
assert.Equal(t, http.StatusForbidden, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "Invalid token")
|
||||
|
||||
// invalid audience
|
||||
req.Header.Set(csrfHeaderToken, tokenString)
|
||||
rr = httptest.NewRecorder()
|
||||
fn.ServeHTTP(rr, req)
|
||||
assert.Equal(t, http.StatusForbidden, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "the token is not valid")
|
||||
|
||||
// invalid IP
|
||||
tokenString = createCSRFToken("172.16.1.2")
|
||||
req.Header.Set(csrfHeaderToken, tokenString)
|
||||
rr = httptest.NewRecorder()
|
||||
fn.ServeHTTP(rr, req)
|
||||
|
@ -729,7 +752,7 @@ func TestCSRFToken(t *testing.T) {
|
|||
assert.Contains(t, rr.Body.String(), "the token is not valid")
|
||||
|
||||
csrfTokenAuth = jwtauth.New("PS256", util.GenerateRandomBytes(32), nil)
|
||||
tokenString = createCSRFToken()
|
||||
tokenString = createCSRFToken("")
|
||||
assert.Empty(t, tokenString)
|
||||
|
||||
csrfTokenAuth = jwtauth.New(jwa.HS256.String(), util.GenerateRandomBytes(32), nil)
|
||||
|
@ -765,7 +788,7 @@ func TestCreateTokenError(t *testing.T) {
|
|||
form := make(url.Values)
|
||||
form.Set("username", admin.Username)
|
||||
form.Set("password", admin.Password)
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken("127.0.0.1"))
|
||||
req, _ = http.NewRequest(http.MethodPost, webAdminLoginPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
req.RemoteAddr = "127.0.0.1:1234"
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
@ -905,7 +928,7 @@ func TestCreateTokenError(t *testing.T) {
|
|||
form = make(url.Values)
|
||||
form.Set("username", user.Username)
|
||||
form.Set("password", "clientpwd")
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken("127.0.0.1"))
|
||||
req, _ = http.NewRequest(http.MethodPost, webClientLoginPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
req.RemoteAddr = "127.0.0.1:4567"
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
@ -1086,7 +1109,7 @@ func TestCookieExpiration(t *testing.T) {
|
|||
claims[claimPermissionsKey] = admin.Permissions
|
||||
claims[jwt.SubjectKey] = admin.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
claims[jwt.AudienceKey] = tokenAudienceAPI
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceAPI}
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
|
@ -1121,7 +1144,7 @@ func TestCookieExpiration(t *testing.T) {
|
|||
claims[claimPermissionsKey] = admin.Permissions
|
||||
claims[jwt.SubjectKey] = admin.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
claims[jwt.AudienceKey] = tokenAudienceAPI
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceAPI}
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
|
@ -1159,7 +1182,7 @@ func TestCookieExpiration(t *testing.T) {
|
|||
claims[claimPermissionsKey] = user.Filters.WebClient
|
||||
claims[jwt.SubjectKey] = user.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
claims[jwt.AudienceKey] = tokenAudienceWebClient
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceWebClient}
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -1191,7 +1214,7 @@ func TestCookieExpiration(t *testing.T) {
|
|||
claims[claimPermissionsKey] = user.Filters.WebClient
|
||||
claims[jwt.SubjectKey] = user.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
claims[jwt.AudienceKey] = tokenAudienceWebClient
|
||||
claims[jwt.AudienceKey] = []string{tokenAudienceWebClient}
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -1520,7 +1543,7 @@ func TestProxyHeaders(t *testing.T) {
|
|||
form := make(url.Values)
|
||||
form.Set("username", username)
|
||||
form.Set("password", password)
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken(testIP))
|
||||
req, err = http.NewRequest(http.MethodPost, webAdminLoginPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
assert.NoError(t, err)
|
||||
req.RemoteAddr = testIP
|
||||
|
@ -1530,6 +1553,7 @@ func TestProxyHeaders(t *testing.T) {
|
|||
assert.Equal(t, http.StatusOK, rr.Code, rr.Body.String())
|
||||
assert.Contains(t, rr.Body.String(), "login from IP 10.29.1.9 not allowed")
|
||||
|
||||
form.Set(csrfFormToken, createCSRFToken(validForwardedFor))
|
||||
req, err = http.NewRequest(http.MethodPost, webAdminLoginPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
assert.NoError(t, err)
|
||||
req.RemoteAddr = testIP
|
||||
|
@ -2069,7 +2093,7 @@ func TestInvalidClaims(t *testing.T) {
|
|||
token, err := c.createTokenResponse(server.tokenAuth, tokenAudienceWebClient, "")
|
||||
assert.NoError(t, err)
|
||||
form := make(url.Values)
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken(""))
|
||||
form.Set("public_keys", "")
|
||||
req, _ := http.NewRequest(http.MethodPost, webClientProfilePath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
@ -2089,7 +2113,7 @@ func TestInvalidClaims(t *testing.T) {
|
|||
token, err = c.createTokenResponse(server.tokenAuth, tokenAudienceWebAdmin, "")
|
||||
assert.NoError(t, err)
|
||||
form = make(url.Values)
|
||||
form.Set(csrfFormToken, createCSRFToken())
|
||||
form.Set(csrfFormToken, createCSRFToken(""))
|
||||
form.Set("allow_api_key_auth", "")
|
||||
req, _ = http.NewRequest(http.MethodPost, webAdminProfilePath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
@ -2400,7 +2424,7 @@ func TestWebAdminSetupWithInstallCode(t *testing.T) {
|
|||
}
|
||||
|
||||
form := make(url.Values)
|
||||
csrfToken := createCSRFToken()
|
||||
csrfToken := createCSRFToken("")
|
||||
form.Set("_form_token", csrfToken)
|
||||
form.Set("install_code", "12345")
|
||||
form.Set("username", defaultAdminUsername)
|
||||
|
|
|
@ -77,7 +77,7 @@ func validateJWTToken(w http.ResponseWriter, r *http.Request, audience tokenAudi
|
|||
return errInvalidToken
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if ipAddr != "" && !strings.Contains(token.JwtID(), ipAddr) {
|
||||
if !util.IsStringInSlice(ipAddr, token.Audience()) {
|
||||
logger.Debug(logSender, "", "the token with id %#v is not valid for the ip address %#v", token.JwtID(), ipAddr)
|
||||
doRedirect("Your token is not valid", nil)
|
||||
return errInvalidToken
|
||||
|
@ -278,7 +278,13 @@ func verifyCSRFHeader(next http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
if !util.IsStringInSlice(tokenAudienceCSRF, token.Audience()) {
|
||||
logger.Debug(logSender, "", "error validating CSRF header audience")
|
||||
logger.Debug(logSender, "", "error validating CSRF header token audience")
|
||||
sendAPIResponse(w, r, errors.New("the token is not valid"), "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if !util.IsStringInSlice(util.GetIPFromRemoteAddress(r.RemoteAddr), token.Audience()) {
|
||||
logger.Debug(logSender, "", "error validating CSRF header IP audience")
|
||||
sendAPIResponse(w, r, errors.New("the token is not valid"), "", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -81,7 +81,10 @@ func setIDTokenClaims(idToken *oidc.IDToken, claims []byte) {
|
|||
}
|
||||
|
||||
func TestOIDCInitialization(t *testing.T) {
|
||||
config := OIDC{
|
||||
config := OIDC{}
|
||||
err := config.initialize()
|
||||
assert.NoError(t, err)
|
||||
config = OIDC{
|
||||
ClientID: "sftpgo-client",
|
||||
ClientSecret: "jRsmE0SWnuZjP7djBqNq0mrf8QN77j2c",
|
||||
ConfigURL: fmt.Sprintf("http://%v/", oidcMockAddr),
|
||||
|
@ -89,7 +92,7 @@ func TestOIDCInitialization(t *testing.T) {
|
|||
UsernameField: "preferred_username",
|
||||
RoleField: "sftpgo_role",
|
||||
}
|
||||
err := config.initialize()
|
||||
err = config.initialize()
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "oidc: unable to initialize provider")
|
||||
}
|
||||
|
|
163
httpd/server.go
163
httpd/server.go
|
@ -133,12 +133,12 @@ func (s *httpdServer) refreshCookie(next http.Handler) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderClientLoginPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderClientLoginPage(w http.ResponseWriter, error, ip string) {
|
||||
data := loginPage{
|
||||
CurrentURL: webClientLoginPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ func (s *httpdServer) handleWebClientChangePwdPost(w http.ResponseWriter, r *htt
|
|||
s.renderClientChangePasswordPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), util.GetIPFromRemoteAddress(r.RemoteAddr)); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -189,48 +189,48 @@ func (s *httpdServer) handleClientWebLogin(w http.ResponseWriter, r *http.Reques
|
|||
http.Redirect(w, r, webAdminSetupPath, http.StatusFound)
|
||||
return
|
||||
}
|
||||
s.renderClientLoginPage(w, getFlashMessage(w, r))
|
||||
s.renderClientLoginPage(w, getFlashMessage(w, r), util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebClientLoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderClientLoginPage(w, err.Error())
|
||||
s.renderClientLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
protocol := common.ProtocolHTTP
|
||||
username := r.Form.Get("username")
|
||||
password := r.Form.Get("password")
|
||||
if username == "" || password == "" {
|
||||
updateLoginMetrics(&dataprovider.User{BaseUser: sdk.BaseUser{Username: username}},
|
||||
dataprovider.LoginMethodPassword, ipAddr, common.ErrNoCredentials)
|
||||
s.renderClientLoginPage(w, "Invalid credentials")
|
||||
s.renderClientLoginPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
updateLoginMetrics(&dataprovider.User{BaseUser: sdk.BaseUser{Username: username}},
|
||||
dataprovider.LoginMethodPassword, ipAddr, err)
|
||||
s.renderClientLoginPage(w, err.Error())
|
||||
s.renderClientLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
|
||||
if err := common.Config.ExecutePostConnectHook(ipAddr, protocol); err != nil {
|
||||
s.renderClientLoginPage(w, fmt.Sprintf("access denied by post connect hook: %v", err))
|
||||
s.renderClientLoginPage(w, fmt.Sprintf("access denied by post connect hook: %v", err), ipAddr)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := dataprovider.CheckUserAndPass(username, password, ipAddr, protocol)
|
||||
if err != nil {
|
||||
updateLoginMetrics(&user, dataprovider.LoginMethodPassword, ipAddr, err)
|
||||
s.renderClientLoginPage(w, dataprovider.ErrInvalidCredentials.Error())
|
||||
s.renderClientLoginPage(w, dataprovider.ErrInvalidCredentials.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
connectionID := fmt.Sprintf("%v_%v", protocol, xid.New().String())
|
||||
if err := checkHTTPClientUser(&user, r, connectionID); err != nil {
|
||||
updateLoginMetrics(&user, dataprovider.LoginMethodPassword, ipAddr, err)
|
||||
s.renderClientLoginPage(w, err.Error())
|
||||
s.renderClientLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ func (s *httpdServer) handleWebClientLoginPost(w http.ResponseWriter, r *http.Re
|
|||
if err != nil {
|
||||
logger.Warn(logSender, connectionID, "unable to check fs root: %v", err)
|
||||
updateLoginMetrics(&user, dataprovider.LoginMethodPassword, ipAddr, common.ErrInternalFailure)
|
||||
s.renderClientLoginPage(w, err.Error())
|
||||
s.renderClientLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.loginUser(w, r, &user, connectionID, ipAddr, false, s.renderClientLoginPage)
|
||||
|
@ -247,27 +247,29 @@ func (s *httpdServer) handleWebClientLoginPost(w http.ResponseWriter, r *http.Re
|
|||
|
||||
func (s *httpdServer) handleWebClientPasswordResetPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderClientResetPwdPage(w, err.Error())
|
||||
s.renderClientResetPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
_, user, err := handleResetPassword(r, r.Form.Get("code"), r.Form.Get("password"), false)
|
||||
if err != nil {
|
||||
if e, ok := err.(*util.ValidationError); ok {
|
||||
s.renderClientResetPwdPage(w, e.GetErrorString())
|
||||
s.renderClientResetPwdPage(w, e.GetErrorString(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.renderClientResetPwdPage(w, err.Error())
|
||||
s.renderClientResetPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
connectionID := fmt.Sprintf("%v_%v", getProtocolFromRequest(r), xid.New().String())
|
||||
if err := checkHTTPClientUser(user, r, connectionID); err != nil {
|
||||
s.renderClientResetPwdPage(w, fmt.Sprintf("Password reset successfully but unable to login: %v", err.Error()))
|
||||
s.renderClientResetPwdPage(w, fmt.Sprintf("Password reset successfully but unable to login: %v", err.Error()), ipAddr)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -275,10 +277,9 @@ func (s *httpdServer) handleWebClientPasswordResetPost(w http.ResponseWriter, r
|
|||
err = user.CheckFsRoot(connectionID)
|
||||
if err != nil {
|
||||
logger.Warn(logSender, connectionID, "unable to check fs root: %v", err)
|
||||
s.renderClientResetPwdPage(w, fmt.Sprintf("Password reset successfully but unable to login: %v", err.Error()))
|
||||
s.renderClientResetPwdPage(w, fmt.Sprintf("Password reset successfully but unable to login: %v", err.Error()), ipAddr)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
s.loginUser(w, r, user, connectionID, ipAddr, false, s.renderClientResetPwdPage)
|
||||
}
|
||||
|
||||
|
@ -289,27 +290,28 @@ func (s *httpdServer) handleWebClientTwoFactorRecoveryPost(w http.ResponseWriter
|
|||
s.renderNotFoundPage(w, r, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderClientTwoFactorRecoveryPage(w, err.Error())
|
||||
s.renderClientTwoFactorRecoveryPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
username := claims.Username
|
||||
recoveryCode := r.Form.Get("recovery_code")
|
||||
if username == "" || recoveryCode == "" {
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid credentials")
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
s.renderClientTwoFactorRecoveryPage(w, err.Error())
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientTwoFactorRecoveryPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(username)
|
||||
if err != nil {
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid credentials")
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if !user.Filters.TOTPConfig.Enabled || !util.IsStringInSlice(common.ProtocolHTTP, user.Filters.TOTPConfig.Protocols) {
|
||||
s.renderClientTwoFactorPage(w, "Two factory authentication is not enabled")
|
||||
s.renderClientTwoFactorPage(w, "Two factory authentication is not enabled", ipAddr)
|
||||
return
|
||||
}
|
||||
for idx, code := range user.Filters.RecoveryCodes {
|
||||
|
@ -319,23 +321,23 @@ func (s *httpdServer) handleWebClientTwoFactorRecoveryPost(w http.ResponseWriter
|
|||
}
|
||||
if code.Secret.GetPayload() == recoveryCode {
|
||||
if code.Used {
|
||||
s.renderClientTwoFactorRecoveryPage(w, "This recovery code was already used")
|
||||
s.renderClientTwoFactorRecoveryPage(w, "This recovery code was already used", ipAddr)
|
||||
return
|
||||
}
|
||||
user.Filters.RecoveryCodes[idx].Used = true
|
||||
err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, ipAddr)
|
||||
if err != nil {
|
||||
logger.Warn(logSender, "", "unable to set the recovery code %#v as used: %v", recoveryCode, err)
|
||||
s.renderClientInternalServerErrorPage(w, r, errors.New("unable to set the recovery code as used"))
|
||||
return
|
||||
}
|
||||
connectionID := fmt.Sprintf("%v_%v", getProtocolFromRequest(r), xid.New().String())
|
||||
s.loginUser(w, r, &user, connectionID, util.GetIPFromRemoteAddress(r.RemoteAddr), true,
|
||||
s.loginUser(w, r, &user, connectionID, ipAddr, true,
|
||||
s.renderClientTwoFactorRecoveryPage)
|
||||
return
|
||||
}
|
||||
}
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid recovery code")
|
||||
s.renderClientTwoFactorRecoveryPage(w, "Invalid recovery code", ipAddr)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebClientTwoFactorPost(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -345,27 +347,28 @@ func (s *httpdServer) handleWebClientTwoFactorPost(w http.ResponseWriter, r *htt
|
|||
s.renderNotFoundPage(w, r, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderClientTwoFactorPage(w, err.Error())
|
||||
s.renderClientTwoFactorPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
username := claims.Username
|
||||
passcode := r.Form.Get("passcode")
|
||||
if username == "" || passcode == "" {
|
||||
s.renderClientTwoFactorPage(w, "Invalid credentials")
|
||||
s.renderClientTwoFactorPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
s.renderClientTwoFactorPage(w, err.Error())
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientTwoFactorPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(username)
|
||||
if err != nil {
|
||||
s.renderClientTwoFactorPage(w, "Invalid credentials")
|
||||
s.renderClientTwoFactorPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if !user.Filters.TOTPConfig.Enabled || !util.IsStringInSlice(common.ProtocolHTTP, user.Filters.TOTPConfig.Protocols) {
|
||||
s.renderClientTwoFactorPage(w, "Two factory authentication is not enabled")
|
||||
s.renderClientTwoFactorPage(w, "Two factory authentication is not enabled", ipAddr)
|
||||
return
|
||||
}
|
||||
err = user.Filters.TOTPConfig.Secret.Decrypt()
|
||||
|
@ -376,44 +379,45 @@ func (s *httpdServer) handleWebClientTwoFactorPost(w http.ResponseWriter, r *htt
|
|||
match, err := mfa.ValidateTOTPPasscode(user.Filters.TOTPConfig.ConfigName, passcode,
|
||||
user.Filters.TOTPConfig.Secret.GetPayload())
|
||||
if !match || err != nil {
|
||||
s.renderClientTwoFactorPage(w, "Invalid authentication code")
|
||||
s.renderClientTwoFactorPage(w, "Invalid authentication code", ipAddr)
|
||||
return
|
||||
}
|
||||
connectionID := fmt.Sprintf("%v_%v", getProtocolFromRequest(r), xid.New().String())
|
||||
s.loginUser(w, r, &user, connectionID, util.GetIPFromRemoteAddress(r.RemoteAddr), true, s.renderClientTwoFactorPage)
|
||||
s.loginUser(w, r, &user, connectionID, ipAddr, true, s.renderClientTwoFactorPage)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminTwoFactorRecoveryPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
||||
|
||||
claims, err := getTokenClaims(r)
|
||||
if err != nil {
|
||||
s.renderNotFoundPage(w, r, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderTwoFactorRecoveryPage(w, err.Error())
|
||||
s.renderTwoFactorRecoveryPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
username := claims.Username
|
||||
recoveryCode := r.Form.Get("recovery_code")
|
||||
if username == "" || recoveryCode == "" {
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid credentials")
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
s.renderTwoFactorRecoveryPage(w, err.Error())
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderTwoFactorRecoveryPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
admin, err := dataprovider.AdminExists(username)
|
||||
if err != nil {
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid credentials")
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if !admin.Filters.TOTPConfig.Enabled {
|
||||
s.renderTwoFactorRecoveryPage(w, "Two factory authentication is not enabled")
|
||||
s.renderTwoFactorRecoveryPage(w, "Two factory authentication is not enabled", ipAddr)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
for idx, code := range admin.Filters.RecoveryCodes {
|
||||
if err := code.Secret.Decrypt(); err != nil {
|
||||
s.renderInternalServerErrorPage(w, r, fmt.Errorf("unable to decrypt recovery code: %w", err))
|
||||
|
@ -421,7 +425,7 @@ func (s *httpdServer) handleWebAdminTwoFactorRecoveryPost(w http.ResponseWriter,
|
|||
}
|
||||
if code.Secret.GetPayload() == recoveryCode {
|
||||
if code.Used {
|
||||
s.renderTwoFactorRecoveryPage(w, "This recovery code was already used")
|
||||
s.renderTwoFactorRecoveryPage(w, "This recovery code was already used", ipAddr)
|
||||
return
|
||||
}
|
||||
admin.Filters.RecoveryCodes[idx].Used = true
|
||||
|
@ -435,7 +439,7 @@ func (s *httpdServer) handleWebAdminTwoFactorRecoveryPost(w http.ResponseWriter,
|
|||
return
|
||||
}
|
||||
}
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid recovery code")
|
||||
s.renderTwoFactorRecoveryPage(w, "Invalid recovery code", ipAddr)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminTwoFactorPost(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -445,27 +449,28 @@ func (s *httpdServer) handleWebAdminTwoFactorPost(w http.ResponseWriter, r *http
|
|||
s.renderNotFoundPage(w, r, nil)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderTwoFactorPage(w, err.Error())
|
||||
s.renderTwoFactorPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
username := claims.Username
|
||||
passcode := r.Form.Get("passcode")
|
||||
if username == "" || passcode == "" {
|
||||
s.renderTwoFactorPage(w, "Invalid credentials")
|
||||
s.renderTwoFactorPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
s.renderTwoFactorPage(w, err.Error())
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderTwoFactorPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
admin, err := dataprovider.AdminExists(username)
|
||||
if err != nil {
|
||||
s.renderTwoFactorPage(w, "Invalid credentials")
|
||||
s.renderTwoFactorPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if !admin.Filters.TOTPConfig.Enabled {
|
||||
s.renderTwoFactorPage(w, "Two factory authentication is not enabled")
|
||||
s.renderTwoFactorPage(w, "Two factory authentication is not enabled", ipAddr)
|
||||
return
|
||||
}
|
||||
err = admin.Filters.TOTPConfig.Secret.Decrypt()
|
||||
|
@ -476,43 +481,44 @@ func (s *httpdServer) handleWebAdminTwoFactorPost(w http.ResponseWriter, r *http
|
|||
match, err := mfa.ValidateTOTPPasscode(admin.Filters.TOTPConfig.ConfigName, passcode,
|
||||
admin.Filters.TOTPConfig.Secret.GetPayload())
|
||||
if !match || err != nil {
|
||||
s.renderTwoFactorPage(w, "Invalid authentication code")
|
||||
s.renderTwoFactorPage(w, "Invalid authentication code", ipAddr)
|
||||
return
|
||||
}
|
||||
s.loginAdmin(w, r, &admin, true, s.renderTwoFactorPage, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
s.loginAdmin(w, r, &admin, true, s.renderTwoFactorPage, ipAddr)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminLoginPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
s.renderAdminLoginPage(w, err.Error())
|
||||
s.renderAdminLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
username := r.Form.Get("username")
|
||||
password := r.Form.Get("password")
|
||||
if username == "" || password == "" {
|
||||
s.renderAdminLoginPage(w, "Invalid credentials")
|
||||
s.renderAdminLoginPage(w, "Invalid credentials", ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
s.renderAdminLoginPage(w, err.Error())
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderAdminLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
admin, err := dataprovider.CheckAdminAndPass(username, password, ipAddr)
|
||||
if err != nil {
|
||||
s.renderAdminLoginPage(w, err.Error())
|
||||
s.renderAdminLoginPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.loginAdmin(w, r, &admin, false, s.renderAdminLoginPage, ipAddr)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderAdminLoginPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderAdminLoginPage(w http.ResponseWriter, error, ip string) {
|
||||
data := loginPage{
|
||||
CurrentURL: webAdminLoginPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
}
|
||||
|
@ -534,7 +540,7 @@ func (s *httpdServer) handleWebAdminLogin(w http.ResponseWriter, r *http.Request
|
|||
http.Redirect(w, r, webAdminSetupPath, http.StatusFound)
|
||||
return
|
||||
}
|
||||
s.renderAdminLoginPage(w, getFlashMessage(w, r))
|
||||
s.renderAdminLoginPage(w, getFlashMessage(w, r), util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminLogout(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -553,7 +559,7 @@ func (s *httpdServer) handleWebAdminChangePwdPost(w http.ResponseWriter, r *http
|
|||
s.renderChangePasswordPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), util.GetIPFromRemoteAddress(r.RemoteAddr)); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -568,26 +574,28 @@ func (s *httpdServer) handleWebAdminChangePwdPost(w http.ResponseWriter, r *http
|
|||
|
||||
func (s *httpdServer) handleWebAdminPasswordResetPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxLoginBodySize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderResetPwdPage(w, err.Error())
|
||||
s.renderResetPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
admin, _, err := handleResetPassword(r, r.Form.Get("code"), r.Form.Get("password"), true)
|
||||
if err != nil {
|
||||
if e, ok := err.(*util.ValidationError); ok {
|
||||
s.renderResetPwdPage(w, e.GetErrorString())
|
||||
s.renderResetPwdPage(w, e.GetErrorString(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.renderResetPwdPage(w, err.Error())
|
||||
s.renderResetPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
|
||||
s.loginAdmin(w, r, admin, false, s.renderResetPwdPage, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
s.loginAdmin(w, r, admin, false, s.renderResetPwdPage, ipAddr)
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -601,7 +609,8 @@ func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Req
|
|||
s.renderAdminSetupPage(w, r, "", err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -631,7 +640,6 @@ func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Req
|
|||
Status: 1,
|
||||
Permissions: []string{dataprovider.PermAdminAny},
|
||||
}
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
err = dataprovider.AddAdmin(&admin, username, ipAddr)
|
||||
if err != nil {
|
||||
s.renderAdminSetupPage(w, r, username, err.Error())
|
||||
|
@ -642,7 +650,7 @@ func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Req
|
|||
|
||||
func (s *httpdServer) loginUser(
|
||||
w http.ResponseWriter, r *http.Request, user *dataprovider.User, connectionID, ipAddr string,
|
||||
isSecondFactorAuth bool, errorFunc func(w http.ResponseWriter, error string),
|
||||
isSecondFactorAuth bool, errorFunc func(w http.ResponseWriter, error, ip string),
|
||||
) {
|
||||
c := jwtTokenClaims{
|
||||
Username: user.Username,
|
||||
|
@ -662,7 +670,7 @@ func (s *httpdServer) loginUser(
|
|||
if err != nil {
|
||||
logger.Warn(logSender, connectionID, "unable to set user login cookie %v", err)
|
||||
updateLoginMetrics(user, dataprovider.LoginMethodPassword, ipAddr, common.ErrInternalFailure)
|
||||
errorFunc(w, err.Error())
|
||||
errorFunc(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if isSecondFactorAuth {
|
||||
|
@ -679,7 +687,8 @@ func (s *httpdServer) loginUser(
|
|||
|
||||
func (s *httpdServer) loginAdmin(
|
||||
w http.ResponseWriter, r *http.Request, admin *dataprovider.Admin,
|
||||
isSecondFactorAuth bool, errorFunc func(w http.ResponseWriter, error string), ip string,
|
||||
isSecondFactorAuth bool, errorFunc func(w http.ResponseWriter, error, ip string),
|
||||
ipAddr string,
|
||||
) {
|
||||
c := jwtTokenClaims{
|
||||
Username: admin.Username,
|
||||
|
@ -692,14 +701,14 @@ func (s *httpdServer) loginAdmin(
|
|||
audience = tokenAudienceWebAdminPartial
|
||||
}
|
||||
|
||||
err := c.createAndSetCookie(w, r, s.tokenAuth, audience, ip)
|
||||
err := c.createAndSetCookie(w, r, s.tokenAuth, audience, ipAddr)
|
||||
if err != nil {
|
||||
logger.Warn(logSender, "", "unable to set admin login cookie %v", err)
|
||||
if errorFunc == nil {
|
||||
s.renderAdminSetupPage(w, r, admin.Username, err.Error())
|
||||
return
|
||||
}
|
||||
errorFunc(w, err.Error())
|
||||
errorFunc(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if isSecondFactorAuth {
|
||||
|
|
|
@ -376,7 +376,7 @@ func loadAdminTemplates(templatesPath string) {
|
|||
func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request) basePage {
|
||||
var csrfToken string
|
||||
if currentURL != "" {
|
||||
csrfToken = createCSRFToken()
|
||||
csrfToken = createCSRFToken(util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
return basePage{
|
||||
Title: title,
|
||||
|
@ -458,11 +458,11 @@ func (s *httpdServer) renderNotFoundPage(w http.ResponseWriter, r *http.Request,
|
|||
s.renderMessagePage(w, r, page404Title, page404Body, http.StatusNotFound, err, "")
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderForgotPwdPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderForgotPwdPage(w http.ResponseWriter, error, ip string) {
|
||||
data := forgotPwdPage{
|
||||
CurrentURL: webAdminForgotPwdPath,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
Title: pageForgotPwdTitle,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -470,11 +470,11 @@ func (s *httpdServer) renderForgotPwdPage(w http.ResponseWriter, error string) {
|
|||
renderAdminTemplate(w, templateForgotPassword, data)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderResetPwdPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderResetPwdPage(w http.ResponseWriter, error, ip string) {
|
||||
data := resetPwdPage{
|
||||
CurrentURL: webAdminResetPwdPath,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
Title: pageResetPwdTitle,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -482,12 +482,12 @@ func (s *httpdServer) renderResetPwdPage(w http.ResponseWriter, error string) {
|
|||
renderAdminTemplate(w, templateResetPassword, data)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderTwoFactorPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderTwoFactorPage(w http.ResponseWriter, error, ip string) {
|
||||
data := twoFactorPage{
|
||||
CurrentURL: webAdminTwoFactorPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
RecoveryURL: webAdminTwoFactorRecoveryPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -495,12 +495,12 @@ func (s *httpdServer) renderTwoFactorPage(w http.ResponseWriter, error string) {
|
|||
renderAdminTemplate(w, templateTwoFactor, data)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderTwoFactorRecoveryPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderTwoFactorRecoveryPage(w http.ResponseWriter, error, ip string) {
|
||||
data := twoFactorPage{
|
||||
CurrentURL: webAdminTwoFactorRecoveryPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
}
|
||||
|
@ -1376,27 +1376,29 @@ func (s *httpdServer) handleWebAdminForgotPwd(w http.ResponseWriter, r *http.Req
|
|||
s.renderNotFoundPage(w, r, errors.New("this page does not exist"))
|
||||
return
|
||||
}
|
||||
s.renderForgotPwdPage(w, "")
|
||||
s.renderForgotPwdPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminForgotPwdPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderForgotPwdPage(w, err.Error())
|
||||
s.renderForgotPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
err = handleForgotPassword(r, r.Form.Get("username"), true)
|
||||
if err != nil {
|
||||
if e, ok := err.(*util.ValidationError); ok {
|
||||
s.renderForgotPwdPage(w, e.GetErrorString())
|
||||
s.renderForgotPwdPage(w, e.GetErrorString(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.renderForgotPwdPage(w, err.Error())
|
||||
s.renderForgotPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, webAdminResetPwdPath, http.StatusFound)
|
||||
|
@ -1408,17 +1410,17 @@ func (s *httpdServer) handleWebAdminPasswordReset(w http.ResponseWriter, r *http
|
|||
s.renderNotFoundPage(w, r, errors.New("this page does not exist"))
|
||||
return
|
||||
}
|
||||
s.renderResetPwdPage(w, "")
|
||||
s.renderResetPwdPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminTwoFactor(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
s.renderTwoFactorPage(w, "")
|
||||
s.renderTwoFactorPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminTwoFactorRecovery(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
s.renderTwoFactorRecoveryPage(w, "")
|
||||
s.renderTwoFactorRecoveryPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebAdminMFA(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -1443,7 +1445,8 @@ func (s *httpdServer) handleWebAdminProfilePost(w http.ResponseWriter, r *http.R
|
|||
s.renderProfilePage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1460,7 +1463,7 @@ func (s *httpdServer) handleWebAdminProfilePost(w http.ResponseWriter, r *http.R
|
|||
admin.Filters.AllowAPIKeyAuth = len(r.Form.Get("allow_api_key_auth")) > 0
|
||||
admin.Email = r.Form.Get("email")
|
||||
admin.Description = r.Form.Get("description")
|
||||
err = dataprovider.UpdateAdmin(&admin, dataprovider.ActionExecutorSelf, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateAdmin(&admin, dataprovider.ActionExecutorSelf, ipAddr)
|
||||
if err != nil {
|
||||
s.renderProfilePage(w, r, err.Error())
|
||||
return
|
||||
|
@ -1487,7 +1490,9 @@ func (s *httpdServer) handleWebRestore(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1517,7 +1522,7 @@ func (s *httpdServer) handleWebRestore(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := restoreBackup(backupContent, "", scanQuota, restoreMode, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr)); err != nil {
|
||||
if err := restoreBackup(backupContent, "", scanQuota, restoreMode, claims.Username, ipAddr); err != nil {
|
||||
s.renderMaintenancePage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1594,11 +1599,12 @@ func (s *httpdServer) handleWebAddAdminPost(w http.ResponseWriter, r *http.Reque
|
|||
s.renderAddUpdateAdminPage(w, r, &admin, err.Error(), true)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
err = dataprovider.AddAdmin(&admin, claims.Username, util.GetIPFromRemoteAddress(r.Method))
|
||||
err = dataprovider.AddAdmin(&admin, claims.Username, ipAddr)
|
||||
if err != nil {
|
||||
s.renderAddUpdateAdminPage(w, r, &admin, err.Error(), true)
|
||||
return
|
||||
|
@ -1624,7 +1630,8 @@ func (s *httpdServer) handleWebUpdateAdminPost(w http.ResponseWriter, r *http.Re
|
|||
s.renderAddUpdateAdminPage(w, r, &updatedAdmin, err.Error(), false)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1650,7 +1657,7 @@ func (s *httpdServer) handleWebUpdateAdminPost(w http.ResponseWriter, r *http.Re
|
|||
return
|
||||
}
|
||||
}
|
||||
err = dataprovider.UpdateAdmin(&updatedAdmin, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateAdmin(&updatedAdmin, claims.Username, ipAddr)
|
||||
if err != nil {
|
||||
s.renderAddUpdateAdminPage(w, r, &admin, err.Error(), false)
|
||||
return
|
||||
|
@ -1733,7 +1740,8 @@ func (s *httpdServer) handleWebTemplateFolderPost(w http.ResponseWriter, r *http
|
|||
}
|
||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1772,7 +1780,7 @@ func (s *httpdServer) handleWebTemplateFolderPost(w http.ResponseWriter, r *http
|
|||
render.JSON(w, r, dump)
|
||||
return
|
||||
}
|
||||
if err = RestoreFolders(dump.Folders, "", 1, 0, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr)); err != nil {
|
||||
if err = RestoreFolders(dump.Folders, "", 1, 0, claims.Username, ipAddr); err != nil {
|
||||
s.renderMessagePage(w, r, "Unable to save folders", "Cannot save the defined folders:",
|
||||
getRespStatus(err), err, "")
|
||||
return
|
||||
|
@ -1819,7 +1827,8 @@ func (s *httpdServer) handleWebTemplateUserPost(w http.ResponseWriter, r *http.R
|
|||
s.renderMessagePage(w, r, "Error parsing user fields", "", http.StatusBadRequest, err, "")
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1854,7 +1863,7 @@ func (s *httpdServer) handleWebTemplateUserPost(w http.ResponseWriter, r *http.R
|
|||
render.JSON(w, r, dump)
|
||||
return
|
||||
}
|
||||
if err = RestoreUsers(dump.Users, "", 1, 0, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr)); err != nil {
|
||||
if err = RestoreUsers(dump.Users, "", 1, 0, claims.Username, ipAddr); err != nil {
|
||||
s.renderMessagePage(w, r, "Unable to save users", "Cannot save the defined users:",
|
||||
getRespStatus(err), err, "")
|
||||
return
|
||||
|
@ -1898,11 +1907,12 @@ func (s *httpdServer) handleWebAddUserPost(w http.ResponseWriter, r *http.Reques
|
|||
s.renderUserPage(w, r, &user, userPageModeAdd, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
err = dataprovider.AddUser(&user, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.AddUser(&user, claims.Username, ipAddr)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webUsersPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -1931,7 +1941,8 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
|
|||
s.renderUserPage(w, r, &user, userPageModeUpdate, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1947,7 +1958,7 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
|
|||
user.FsConfig.AzBlobConfig.SASURL, user.FsConfig.GCSConfig.Credentials, user.FsConfig.CryptConfig.Passphrase,
|
||||
user.FsConfig.SFTPConfig.Password, user.FsConfig.SFTPConfig.PrivateKey)
|
||||
|
||||
err = dataprovider.UpdateUser(&updatedUser, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateUser(&updatedUser, claims.Username, ipAddr)
|
||||
if err == nil {
|
||||
if len(r.Form.Get("disconnect")) > 0 {
|
||||
disconnectUser(user.Username)
|
||||
|
@ -1992,7 +2003,8 @@ func (s *httpdServer) handleWebAddFolderPost(w http.ResponseWriter, r *http.Requ
|
|||
}
|
||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -2051,7 +2063,8 @@ func (s *httpdServer) handleWebUpdateFolderPost(w http.ResponseWriter, r *http.R
|
|||
}
|
||||
defer r.MultipartForm.RemoveAll() //nolint:errcheck
|
||||
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -2072,7 +2085,7 @@ func (s *httpdServer) handleWebUpdateFolderPost(w http.ResponseWriter, r *http.R
|
|||
folder.FsConfig.AzBlobConfig.SASURL, folder.FsConfig.GCSConfig.Credentials, folder.FsConfig.CryptConfig.Passphrase,
|
||||
folder.FsConfig.SFTPConfig.Password, folder.FsConfig.SFTPConfig.PrivateKey)
|
||||
|
||||
err = dataprovider.UpdateFolder(updatedFolder, folder.Users, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateFolder(updatedFolder, folder.Users, claims.Username, ipAddr)
|
||||
if err != nil {
|
||||
s.renderFolderPage(w, r, folder, folderPageModeUpdate, err.Error())
|
||||
return
|
||||
|
|
|
@ -314,7 +314,7 @@ func loadClientTemplates(templatesPath string) {
|
|||
func (s *httpdServer) getBaseClientPageData(title, currentURL string, r *http.Request) baseClientPage {
|
||||
var csrfToken string
|
||||
if currentURL != "" {
|
||||
csrfToken = createCSRFToken()
|
||||
csrfToken = createCSRFToken(util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
v := version.Get()
|
||||
|
||||
|
@ -341,11 +341,11 @@ func (s *httpdServer) getBaseClientPageData(title, currentURL string, r *http.Re
|
|||
}
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderClientForgotPwdPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderClientForgotPwdPage(w http.ResponseWriter, error, ip string) {
|
||||
data := forgotPwdPage{
|
||||
CurrentURL: webClientForgotPwdPath,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
Title: pageClientForgotPwdTitle,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -353,11 +353,11 @@ func (s *httpdServer) renderClientForgotPwdPage(w http.ResponseWriter, error str
|
|||
renderClientTemplate(w, templateForgotPassword, data)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderClientResetPwdPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderClientResetPwdPage(w http.ResponseWriter, error, ip string) {
|
||||
data := resetPwdPage{
|
||||
CurrentURL: webClientResetPwdPath,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
Title: pageClientResetPwdTitle,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -405,12 +405,12 @@ func (s *httpdServer) renderClientNotFoundPage(w http.ResponseWriter, r *http.Re
|
|||
s.renderClientMessagePage(w, r, page404Title, page404Body, http.StatusNotFound, err, "")
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderClientTwoFactorPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderClientTwoFactorPage(w http.ResponseWriter, error, ip string) {
|
||||
data := twoFactorPage{
|
||||
CurrentURL: webClientTwoFactorPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
RecoveryURL: webClientTwoFactorRecoveryPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
|
@ -418,12 +418,12 @@ func (s *httpdServer) renderClientTwoFactorPage(w http.ResponseWriter, error str
|
|||
renderClientTemplate(w, templateTwoFactor, data)
|
||||
}
|
||||
|
||||
func (s *httpdServer) renderClientTwoFactorRecoveryPage(w http.ResponseWriter, error string) {
|
||||
func (s *httpdServer) renderClientTwoFactorRecoveryPage(w http.ResponseWriter, error, ip string) {
|
||||
data := twoFactorPage{
|
||||
CurrentURL: webClientTwoFactorRecoveryPath,
|
||||
Version: version.Get().Version,
|
||||
Error: error,
|
||||
CSRFToken: createCSRFToken(),
|
||||
CSRFToken: createCSRFToken(ip),
|
||||
StaticURL: webStaticFilesPath,
|
||||
ExtraCSS: s.binding.ExtraCSS,
|
||||
}
|
||||
|
@ -972,7 +972,8 @@ func (s *httpdServer) handleClientAddSharePost(w http.ResponseWriter, r *http.Re
|
|||
s.renderAddUpdateSharePage(w, r, share, err.Error(), true)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -986,7 +987,7 @@ func (s *httpdServer) handleClientAddSharePost(w http.ResponseWriter, r *http.Re
|
|||
return
|
||||
}
|
||||
}
|
||||
err = dataprovider.AddShare(share, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.AddShare(share, claims.Username, ipAddr)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webClientSharesPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -1015,7 +1016,8 @@ func (s *httpdServer) handleClientUpdateSharePost(w http.ResponseWriter, r *http
|
|||
s.renderAddUpdateSharePage(w, r, updatedShare, err.Error(), false)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1030,7 +1032,7 @@ func (s *httpdServer) handleClientUpdateSharePost(w http.ResponseWriter, r *http
|
|||
return
|
||||
}
|
||||
}
|
||||
err = dataprovider.UpdateShare(updatedShare, claims.Username, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateShare(updatedShare, claims.Username, ipAddr)
|
||||
if err == nil {
|
||||
http.Redirect(w, r, webClientSharesPath, http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -1090,7 +1092,8 @@ func (s *httpdServer) handleWebClientProfilePost(w http.ResponseWriter, r *http.
|
|||
s.renderClientProfilePage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1118,7 +1121,7 @@ func (s *httpdServer) handleWebClientProfilePost(w http.ResponseWriter, r *http.
|
|||
user.Email = r.Form.Get("email")
|
||||
user.Description = r.Form.Get("description")
|
||||
}
|
||||
err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, ipAddr)
|
||||
if err != nil {
|
||||
s.renderClientProfilePage(w, r, err.Error())
|
||||
return
|
||||
|
@ -1134,12 +1137,12 @@ func (s *httpdServer) handleWebClientMFA(w http.ResponseWriter, r *http.Request)
|
|||
|
||||
func (s *httpdServer) handleWebClientTwoFactor(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
s.renderClientTwoFactorPage(w, "")
|
||||
s.renderClientTwoFactorPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebClientTwoFactorRecovery(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
s.renderClientTwoFactorRecoveryPage(w, "")
|
||||
s.renderClientTwoFactorRecoveryPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func getShareFromPostFields(r *http.Request) (*dataprovider.Share, error) {
|
||||
|
@ -1181,17 +1184,19 @@ func (s *httpdServer) handleWebClientForgotPwd(w http.ResponseWriter, r *http.Re
|
|||
s.renderClientNotFoundPage(w, r, errors.New("this page does not exist"))
|
||||
return
|
||||
}
|
||||
s.renderClientForgotPwdPage(w, "")
|
||||
s.renderClientForgotPwdPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleWebClientForgotPwdPost(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
s.renderClientForgotPwdPage(w, err.Error())
|
||||
s.renderClientForgotPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil {
|
||||
if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
||||
s.renderClientForbiddenPage(w, r, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1199,10 +1204,10 @@ func (s *httpdServer) handleWebClientForgotPwdPost(w http.ResponseWriter, r *htt
|
|||
err = handleForgotPassword(r, username, false)
|
||||
if err != nil {
|
||||
if e, ok := err.(*util.ValidationError); ok {
|
||||
s.renderClientForgotPwdPage(w, e.GetErrorString())
|
||||
s.renderClientForgotPwdPage(w, e.GetErrorString(), ipAddr)
|
||||
return
|
||||
}
|
||||
s.renderClientForgotPwdPage(w, err.Error())
|
||||
s.renderClientForgotPwdPage(w, err.Error(), ipAddr)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, webClientResetPwdPath, http.StatusFound)
|
||||
|
@ -1214,7 +1219,7 @@ func (s *httpdServer) handleWebClientPasswordReset(w http.ResponseWriter, r *htt
|
|||
s.renderClientNotFoundPage(w, r, errors.New("this page does not exist"))
|
||||
return
|
||||
}
|
||||
s.renderClientResetPwdPage(w, "")
|
||||
s.renderClientResetPwdPage(w, "", util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
}
|
||||
|
||||
func (s *httpdServer) handleClientViewPDF(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
Loading…
Reference in a new issue