2020-11-05 13:37:51 -05:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
|
2021-03-22 17:51:37 -04:00
|
|
|
csrf "github.com/utrack/gin-csrf"
|
|
|
|
|
2020-11-05 13:37:51 -05:00
|
|
|
"github.com/gin-gonic/gin"
|
2021-02-24 15:24:45 -05:00
|
|
|
"github.com/h44z/wg-portal/internal/authentication"
|
|
|
|
"github.com/h44z/wg-portal/internal/users"
|
2021-02-08 16:56:02 -05:00
|
|
|
"github.com/sirupsen/logrus"
|
2020-11-05 13:37:51 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
func (s *Server) GetLogin(c *gin.Context) {
|
2021-02-24 15:24:45 -05:00
|
|
|
currentSession := GetSessionData(c)
|
2020-11-05 13:37:51 -05:00
|
|
|
if currentSession.LoggedIn {
|
|
|
|
c.Redirect(http.StatusSeeOther, "/") // already logged in
|
|
|
|
}
|
|
|
|
|
|
|
|
authError := c.DefaultQuery("err", "")
|
|
|
|
errMsg := "Unknown error occurred, try again!"
|
|
|
|
switch authError {
|
|
|
|
case "missingdata":
|
|
|
|
errMsg = "Invalid login data retrieved, please fill out all fields and try again!"
|
|
|
|
case "authfail":
|
|
|
|
errMsg = "Authentication failed!"
|
|
|
|
case "loginreq":
|
|
|
|
errMsg = "Login required!"
|
|
|
|
}
|
|
|
|
|
|
|
|
c.HTML(http.StatusOK, "login.html", gin.H{
|
|
|
|
"error": authError != "",
|
|
|
|
"message": errMsg,
|
|
|
|
"static": s.getStaticData(),
|
2021-03-22 17:51:37 -04:00
|
|
|
"Csrf": csrf.GetToken(c),
|
2020-11-05 13:37:51 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) PostLogin(c *gin.Context) {
|
2021-02-24 15:24:45 -05:00
|
|
|
currentSession := GetSessionData(c)
|
2020-11-05 13:37:51 -05:00
|
|
|
if currentSession.LoggedIn {
|
|
|
|
// already logged in
|
|
|
|
c.Redirect(http.StatusSeeOther, "/")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
username := strings.ToLower(c.PostForm("username"))
|
|
|
|
password := c.PostForm("password")
|
|
|
|
|
|
|
|
// Validate form input
|
|
|
|
if strings.Trim(username, " ") == "" || strings.Trim(password, " ") == "" {
|
2020-11-10 03:31:02 -05:00
|
|
|
c.Redirect(http.StatusSeeOther, "/auth/login?err=missingdata")
|
2020-11-05 13:37:51 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
// Check user database for an matching entry
|
|
|
|
var loginProvider authentication.AuthProvider
|
|
|
|
email := ""
|
|
|
|
user := s.users.GetUser(username) // retrieve active candidate user from db
|
|
|
|
if user != nil { // existing user
|
|
|
|
loginProvider = s.auth.GetProvider(string(user.Source))
|
|
|
|
if loginProvider == nil {
|
|
|
|
s.GetHandleError(c, http.StatusInternalServerError, "login error", "login provider unavailable")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
authEmail, err := loginProvider.Login(&authentication.AuthContext{
|
|
|
|
Username: username,
|
|
|
|
Password: password,
|
|
|
|
})
|
|
|
|
if err == nil {
|
|
|
|
email = authEmail
|
|
|
|
}
|
|
|
|
} else { // possible new user
|
|
|
|
// Check all available auth backends
|
|
|
|
for _, provider := range s.auth.GetProvidersForType(authentication.AuthProviderTypePassword) {
|
|
|
|
// try to log in to the given provider
|
|
|
|
authEmail, err := provider.Login(&authentication.AuthContext{
|
|
|
|
Username: username,
|
|
|
|
Password: password,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
email = authEmail
|
|
|
|
loginProvider = provider
|
|
|
|
|
|
|
|
// create new user in the database (or reactivate him)
|
|
|
|
userData, err := loginProvider.GetUserModel(&authentication.AuthContext{
|
|
|
|
Username: email,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
s.GetHandleError(c, http.StatusInternalServerError, "login error", err.Error())
|
|
|
|
return
|
|
|
|
}
|
2021-02-26 16:17:04 -05:00
|
|
|
if err := s.CreateUser(users.User{
|
|
|
|
Email: userData.Email,
|
|
|
|
Source: users.UserSource(loginProvider.GetName()),
|
|
|
|
IsAdmin: userData.IsAdmin,
|
|
|
|
Firstname: userData.Firstname,
|
|
|
|
Lastname: userData.Lastname,
|
|
|
|
Phone: userData.Phone,
|
2021-03-22 08:00:02 -04:00
|
|
|
}, s.wg.Cfg.GetDefaultDeviceName()); err != nil {
|
2021-02-24 15:24:45 -05:00
|
|
|
s.GetHandleError(c, http.StatusInternalServerError, "login error", "failed to update user data")
|
|
|
|
return
|
|
|
|
}
|
2021-02-26 16:17:04 -05:00
|
|
|
|
|
|
|
user = s.users.GetUser(username)
|
2021-02-24 15:24:45 -05:00
|
|
|
break
|
|
|
|
}
|
2020-11-05 13:37:51 -05:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
// Check if user is authenticated
|
2021-02-26 16:17:04 -05:00
|
|
|
if email == "" || loginProvider == nil || user == nil {
|
2020-11-10 03:31:02 -05:00
|
|
|
c.Redirect(http.StatusSeeOther, "/auth/login?err=authfail")
|
2020-11-05 13:37:51 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
// Set authenticated session
|
|
|
|
sessionData := GetSessionData(c)
|
|
|
|
sessionData.LoggedIn = true
|
|
|
|
sessionData.IsAdmin = user.IsAdmin
|
|
|
|
sessionData.Email = user.Email
|
|
|
|
sessionData.Firstname = user.Firstname
|
|
|
|
sessionData.Lastname = user.Lastname
|
2021-03-21 07:36:11 -04:00
|
|
|
sessionData.DeviceName = s.wg.Cfg.DeviceNames[0]
|
2020-11-05 13:37:51 -05:00
|
|
|
|
2020-11-16 16:39:41 -05:00
|
|
|
// Check if user already has a peer setup, if not create one
|
2021-03-22 08:00:02 -04:00
|
|
|
if err := s.CreateUserDefaultPeer(user.Email, s.wg.Cfg.GetDefaultDeviceName()); err != nil {
|
2021-02-26 16:17:04 -05:00
|
|
|
// Not a fatal error, just log it...
|
|
|
|
logrus.Errorf("failed to automatically create vpn peer for %s: %v", sessionData.Email, err)
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
if err := UpdateSessionData(c, sessionData); err != nil {
|
2020-11-10 03:31:02 -05:00
|
|
|
s.GetHandleError(c, http.StatusInternalServerError, "login error", "failed to save session")
|
2020-11-05 13:37:51 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
c.Redirect(http.StatusSeeOther, "/")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) GetLogout(c *gin.Context) {
|
2021-02-24 15:24:45 -05:00
|
|
|
currentSession := GetSessionData(c)
|
2020-11-05 13:37:51 -05:00
|
|
|
|
|
|
|
if !currentSession.LoggedIn { // Not logged in
|
2020-11-10 03:31:02 -05:00
|
|
|
c.Redirect(http.StatusSeeOther, "/")
|
2020-11-05 13:37:51 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
if err := DestroySessionData(c); err != nil {
|
2020-11-10 03:31:02 -05:00
|
|
|
s.GetHandleError(c, http.StatusInternalServerError, "logout error", "failed to destroy session")
|
2020-11-05 13:37:51 -05:00
|
|
|
return
|
|
|
|
}
|
2020-11-10 03:31:02 -05:00
|
|
|
c.Redirect(http.StatusSeeOther, "/")
|
2020-11-05 13:37:51 -05:00
|
|
|
}
|