2018-11-07 10:10:51 +00:00
|
|
|
package controllers
|
|
|
|
|
|
|
|
import (
|
2018-11-13 20:39:04 +00:00
|
|
|
"fmt"
|
2018-11-08 07:36:08 +00:00
|
|
|
"multitenantStack/models"
|
2018-11-08 10:21:06 +00:00
|
|
|
companydb "multitenantStack/services/companydb"
|
2018-11-08 07:36:08 +00:00
|
|
|
|
2018-11-08 10:21:06 +00:00
|
|
|
tokenTools "multitenantStack/services/tokenTools"
|
2018-11-07 10:10:51 +00:00
|
|
|
"time"
|
|
|
|
|
2018-11-08 07:36:08 +00:00
|
|
|
"github.com/astaxie/beego/orm"
|
2018-11-07 10:10:51 +00:00
|
|
|
jwt "github.com/dgrijalva/jwt-go"
|
2018-11-13 20:39:04 +00:00
|
|
|
"github.com/kennygrant/sanitize"
|
2018-11-07 10:10:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// AuthController operations for Auth
|
|
|
|
type AuthController struct {
|
|
|
|
BaseController
|
|
|
|
}
|
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
// AuthResponse the format for all responses from auth
|
|
|
|
type AuthResponse struct {
|
|
|
|
Status int `json:"status"`
|
|
|
|
Jwt string `json:"jwt"`
|
|
|
|
User models.CompanyUser `json:"user"`
|
|
|
|
}
|
|
|
|
|
2018-11-07 10:10:51 +00:00
|
|
|
// URLMapping ...
|
|
|
|
func (c *AuthController) URLMapping() {
|
|
|
|
// This block is used to drastically speed up the annotation -> lookup process
|
|
|
|
c.Mapping("Login", c.Login)
|
2018-11-13 20:39:04 +00:00
|
|
|
c.Mapping("Register", c.Register)
|
2018-11-07 10:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Login Get a JWT token for the user
|
|
|
|
// @Title Create
|
|
|
|
// @Description create Auth
|
|
|
|
// @Param body body models.Auth true "body for Auth content"
|
|
|
|
// @Success 201 {object} models.Auth
|
|
|
|
// @Failure 403 body is empty
|
|
|
|
// @router /login [post]
|
|
|
|
func (c *AuthController) Login() {
|
|
|
|
if c.Ctx.Input.Method() != "POST" {
|
2018-11-07 19:13:26 +00:00
|
|
|
c.ServeJSONError("Method not allowed")
|
2018-11-07 10:10:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-08 07:36:08 +00:00
|
|
|
tokenHeader := c.Ctx.Request.Header.Get("X-JWTtoken")
|
|
|
|
if tokenHeader != "" {
|
2018-11-08 10:21:06 +00:00
|
|
|
valid, _ := tokenTools.Validate(tokenHeader)
|
2018-11-08 07:36:08 +00:00
|
|
|
if valid {
|
|
|
|
c.ServeJSONError("You are already logged in")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-11-07 10:10:51 +00:00
|
|
|
|
|
|
|
email := c.GetString("email")
|
|
|
|
password := c.GetString("password")
|
|
|
|
|
2018-11-08 07:36:08 +00:00
|
|
|
if email == "" || password == "" {
|
|
|
|
c.ServeJSONError("Email/Password missing")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-08 10:21:06 +00:00
|
|
|
systemdb := companydb.GetSystemDatabase()
|
|
|
|
|
|
|
|
if systemdb == nil {
|
|
|
|
c.ServeJSONError("Error retrieving User")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
o, err := orm.NewOrmWithDB("postgres", "default", systemdb)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving User")
|
|
|
|
return
|
|
|
|
}
|
2018-11-08 07:36:08 +00:00
|
|
|
|
|
|
|
userCompanyMapping, err := models.GetUserCompanyMapByEmail(o, email)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving User")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-12 10:43:14 +00:00
|
|
|
if !tokenTools.CheckPasswordHash(password, userCompanyMapping.PasswordHash) {
|
2018-11-08 07:36:08 +00:00
|
|
|
c.ServeJSONError("Email/Password incorrect")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
companyName := userCompanyMapping.Company
|
|
|
|
companyUserID := userCompanyMapping.CompanyUserID
|
|
|
|
|
|
|
|
db, err := companydb.GetDatabaseWithName(companyName)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving Company")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
o, err = orm.NewOrmWithDB("postgres", "default", db)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving CompanyData")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
companyUser, err := models.GetCompanyUserById(o, int(companyUserID))
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving Company User")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-07 10:10:51 +00:00
|
|
|
tokenString := ""
|
|
|
|
if email == "admin@admin.at" && password == "my password" {
|
|
|
|
// The jwtClaims are our trusted clientside session
|
2018-11-08 10:21:06 +00:00
|
|
|
tokenString = tokenTools.CreateToken(jwt.MapClaims{
|
2018-11-07 10:10:51 +00:00
|
|
|
"email": email,
|
|
|
|
"companyName": companyName,
|
2018-11-07 19:13:26 +00:00
|
|
|
"companyUserID": companyUserID,
|
|
|
|
"exp": time.Now().Unix() + 3600,
|
2018-11-07 10:10:51 +00:00
|
|
|
})
|
|
|
|
} else {
|
2018-11-07 19:13:26 +00:00
|
|
|
c.ServeJSONError("Invalid user/password")
|
2018-11-07 10:10:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-11-08 10:21:06 +00:00
|
|
|
json := AuthResponse{200, tokenString, *companyUser}
|
2018-11-07 10:10:51 +00:00
|
|
|
c.Data["json"] = &json
|
|
|
|
|
|
|
|
c.ServeJSON()
|
|
|
|
}
|
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
// Register Register a new company and user, create DB and so on
|
|
|
|
// @Title Create
|
|
|
|
// @Description create Auth
|
|
|
|
// @Param body body models.Auth true "body for Auth content"
|
|
|
|
// @Success 201 {object} models.Auth
|
|
|
|
// @Failure 403 body is empty
|
|
|
|
// @router /register [post]
|
|
|
|
func (c *AuthController) Register() {
|
|
|
|
// can be called without jwt token set
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
// needed data:
|
|
|
|
// email
|
|
|
|
// password
|
|
|
|
// companyname
|
|
|
|
// optional: username
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
// Tasks:
|
|
|
|
// create database
|
|
|
|
// create user_company_map entry
|
|
|
|
// create company user
|
|
|
|
// return jwt token and user profile
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
if c.Ctx.Input.Method() != "POST" {
|
|
|
|
c.ServeJSONError("Method not allowed")
|
|
|
|
return
|
|
|
|
}
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
tokenHeader := c.Ctx.Request.Header.Get("X-JWTtoken")
|
|
|
|
if tokenHeader != "" {
|
|
|
|
valid, _ := tokenTools.Validate(tokenHeader)
|
|
|
|
if valid {
|
|
|
|
c.ServeJSONError("You are already logged in")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
email := c.GetString("email")
|
|
|
|
password := c.GetString("password")
|
|
|
|
username := c.GetString("username")
|
|
|
|
companyname := c.GetString("companyname")
|
|
|
|
|
|
|
|
companyname = sanitize.BaseName(companyname)
|
|
|
|
companyname = fmt.Sprintf("company_%s", companyname)
|
|
|
|
|
|
|
|
if email == "" || password == "" || companyname == "" || username == "" {
|
|
|
|
c.ServeJSONError("Email/Password/Companyname missing")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
systemdb := companydb.GetSystemDatabase()
|
|
|
|
|
|
|
|
if systemdb == nil {
|
|
|
|
c.ServeJSONError("Error retrieving data")
|
|
|
|
return
|
|
|
|
}
|
2018-11-07 10:10:51 +00:00
|
|
|
|
2018-11-13 20:39:04 +00:00
|
|
|
o, err := orm.NewOrmWithDB("postgres", "default", systemdb)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error retrieving data")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ucmExists, err := models.GetUserCompanyMapByEmail(o, email)
|
|
|
|
if err != nil && ucmExists != nil {
|
|
|
|
c.ServeJSONError("Error: Email exists!")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if companydb.HasDatabase(companyname) {
|
|
|
|
c.ServeJSONError("Error: Company exists!")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var userCompanyMapping models.UserCompanyMap
|
|
|
|
newHash, _ := tokenTools.HashPassword(password)
|
|
|
|
userCompanyMapping.PasswordHash = newHash
|
|
|
|
userCompanyMapping.Company = companyname
|
|
|
|
userCompanyMapping.Email = email
|
|
|
|
|
|
|
|
ucmID, err := models.AddUserCompanyMap(o, &userCompanyMapping)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONErrorWithError("Error on saving user", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create company
|
|
|
|
newDB, err := companydb.CreateDatabase(companyname)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONErrorWithError("Error on creating DB", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
newO, err := orm.NewOrmWithDB("postgres", "default", newDB)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONErrorWithError("Error retrieving company data", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var companyUser models.CompanyUser
|
|
|
|
companyUser.Name = username
|
|
|
|
companyUser.Profile = "{}"
|
|
|
|
companyUser.Role = 1 //TODO: replacxe with owner constant
|
|
|
|
|
|
|
|
userID, err := models.AddCompanyUser(newO, &companyUser)
|
|
|
|
if err != nil {
|
|
|
|
c.ServeJSONError("Error on saving company user")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// edit usermapping
|
|
|
|
userCompanyMapping.ID = int(ucmID)
|
|
|
|
userCompanyMapping.CompanyUserID = int16(userID)
|
|
|
|
if err := models.UpdateUserCompanyMapById(o, &userCompanyMapping); err != nil {
|
|
|
|
c.ServeJSONError("Error on saving user")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tokenString := ""
|
|
|
|
|
|
|
|
tokenString = tokenTools.CreateToken(jwt.MapClaims{
|
|
|
|
"email": email,
|
|
|
|
"companyName": companyname,
|
|
|
|
"companyUserID": userCompanyMapping.CompanyUserID,
|
|
|
|
"exp": time.Now().Unix() + 3600,
|
|
|
|
})
|
|
|
|
|
|
|
|
json := AuthResponse{200, tokenString, companyUser}
|
|
|
|
c.Data["json"] = &json
|
|
|
|
|
|
|
|
c.ServeJSON()
|
2018-11-07 10:10:51 +00:00
|
|
|
|
|
|
|
}
|