mirror of https://github.com/h44z/wg-portal.git
				
				
				
			
		
			
				
	
	
		
			152 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| package server
 | |
| 
 | |
| import (
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/gin-gonic/gin"
 | |
| 	"github.com/h44z/wg-portal/internal/authentication"
 | |
| 	"github.com/h44z/wg-portal/internal/users"
 | |
| 	"github.com/sirupsen/logrus"
 | |
| )
 | |
| 
 | |
| func (s *Server) GetLogin(c *gin.Context) {
 | |
| 	currentSession := GetSessionData(c)
 | |
| 	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(),
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func (s *Server) PostLogin(c *gin.Context) {
 | |
| 	currentSession := GetSessionData(c)
 | |
| 	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, " ") == "" {
 | |
| 		c.Redirect(http.StatusSeeOther, "/auth/login?err=missingdata")
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// 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
 | |
| 			}
 | |
| 			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,
 | |
| 			}); err != nil {
 | |
| 				s.GetHandleError(c, http.StatusInternalServerError, "login error", "failed to update user data")
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			user = s.users.GetUser(username)
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Check if user is authenticated
 | |
| 	if email == "" || loginProvider == nil || user == nil {
 | |
| 		c.Redirect(http.StatusSeeOther, "/auth/login?err=authfail")
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// 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
 | |
| 
 | |
| 	// Check if user already has a peer setup, if not create one
 | |
| 	if err := s.CreateUserDefaultPeer(user.Email); err != nil {
 | |
| 		// Not a fatal error, just log it...
 | |
| 		logrus.Errorf("failed to automatically create vpn peer for %s: %v", sessionData.Email, err)
 | |
| 	}
 | |
| 
 | |
| 	if err := UpdateSessionData(c, sessionData); err != nil {
 | |
| 		s.GetHandleError(c, http.StatusInternalServerError, "login error", "failed to save session")
 | |
| 		return
 | |
| 	}
 | |
| 	c.Redirect(http.StatusSeeOther, "/")
 | |
| }
 | |
| 
 | |
| func (s *Server) GetLogout(c *gin.Context) {
 | |
| 	currentSession := GetSessionData(c)
 | |
| 
 | |
| 	if !currentSession.LoggedIn { // Not logged in
 | |
| 		c.Redirect(http.StatusSeeOther, "/")
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if err := DestroySessionData(c); err != nil {
 | |
| 		s.GetHandleError(c, http.StatusInternalServerError, "logout error", "failed to destroy session")
 | |
| 		return
 | |
| 	}
 | |
| 	c.Redirect(http.StatusSeeOther, "/")
 | |
| }
 |