package controllers import ( "encoding/json" "errors" "fmt" "multitenantStack/constants" "multitenantStack/models" "multitenantStack/services/companydb" tokenTools "multitenantStack/services/tokenTools" "strconv" "strings" "github.com/astaxie/beego/orm" ) // CompanyUserController operations for CompanyUser type CompanyUserController struct { BaseAPIController } // URLMapping ... func (c *CompanyUserController) URLMapping() { c.Mapping("Post", c.Post) c.Mapping("GetOne", c.GetOne) c.Mapping("GetAll", c.GetAll) c.Mapping("Put", c.Put) c.Mapping("Delete", c.Delete) c.Mapping("DeleteCompany", c.DeleteCompany) } // Post ... // @Title Post // @Description Create a new CompanyUser and his user company mapping // @Param body body models.CompanyUser true "body for CompanyUser content" // @Success 201 {int} models.CompanyUser // @Failure 403 body is empty // @router / [post] func (c *CompanyUserController) Post() { email := c.GetString("email") password := c.GetString("password") name := c.GetString("name") if email == "" || password == "" || name == "" { c.ServeJSONError("Email/Password/Name missing") return } systemdb := companydb.GetSystemDatabase() if systemdb == nil { c.ServeJSONError("Error retrieving User") return } systemO, err := orm.NewOrmWithDB("postgres", "default", systemdb) if err != nil { c.ServeJSONError("Error retrieving User") return } ucmExists, err := models.GetUserCompanyMapByEmail(systemO, email) if ucmExists != nil { fmt.Println(ucmExists) c.ServeJSONError("Error: Email exists!") return } var companyUser models.CompanyUser companyUser.Name = name companyUser.Profile = "{}" companyUser.Role = constants.RoleAdmin companyUserId, err := models.AddCompanyUser(o, &companyUser) if err != nil { c.ServeJSONErrorWithError("Error on saving company user", err) return } var userCompanyMapping models.UserCompanyMap newHash, _ := tokenTools.HashPassword(password) userCompanyMapping.PasswordHash = newHash userCompanyMapping.CompanyUserID = int16(companyUserId) userCompanyMapping.Company = jwtSession.CompanyName userCompanyMapping.Email = email _, err = models.AddUserCompanyMap(systemO, &userCompanyMapping) if err == nil { c.ServeJSONSuccess("Success") return } else { c.ServeJSONErrorWithError("Error on saving user", err) return } } // GetOne ... // @Title Get One // @Description get CompanyUser by id // @Param id path string true "The key for staticblock" // @Success 200 {object} models.CompanyUser // @Failure 403 :id is empty // @router /:id [get] func (c *CompanyUserController) GetOne() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.Atoi(idStr) v, err := models.GetCompanyUserById(o, id) if err != nil { c.ServeJSONErrorWithError("Error", err) } else { c.Data["json"] = v } c.ServeJSON() } // GetAll ... // @Title Get All // @Description get CompanyUser // @Param query query string false "Filter. e.g. col1:v1,col2:v2 ..." // @Param fields query string false "Fields returned. e.g. col1,col2 ..." // @Param sortby query string false "Sorted-by fields. e.g. col1,col2 ..." // @Param order query string false "Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..." // @Param limit query string false "Limit the size of result set. Must be an integer" // @Param offset query string false "Start position of result set. Must be an integer" // @Success 200 {object} models.CompanyUser // @Failure 403 // @router / [get] func (c *CompanyUserController) GetAll() { var fields []string var sortby []string var order []string var query = make(map[string]string) var limit int64 = 10 var offset int64 // fields: col1,col2,entity.col3 if v := c.GetString("fields"); v != "" { fields = strings.Split(v, ",") } // limit: 10 (default is 10) if v, err := c.GetInt64("limit"); err == nil { limit = v } // offset: 0 (default is 0) if v, err := c.GetInt64("offset"); err == nil { offset = v } // sortby: col1,col2 if v := c.GetString("sortby"); v != "" { sortby = strings.Split(v, ",") } // order: desc,asc if v := c.GetString("order"); v != "" { order = strings.Split(v, ",") } // query: k:v,k:v if v := c.GetString("query"); v != "" { for _, cond := range strings.Split(v, ",") { kv := strings.SplitN(cond, ":", 2) if len(kv) != 2 { c.Data["json"] = errors.New("Error: invalid query key/value pair") c.ServeJSON() return } k, v := kv[0], kv[1] query[k] = v } } l, err := models.GetAllCompanyUser(o, query, fields, sortby, order, offset, limit) if err != nil { c.ServeJSONErrorWithError("Error", err) } else { c.Data["json"] = l } c.ServeJSON() } // Put ... // @Title Put // @Description update the CompanyUser // @Param id path string true "The id you want to update" // @Param body body models.CompanyUser true "body for CompanyUser content" // @Success 200 {object} models.CompanyUser // @Failure 403 :id is not int // @router /:id [put] func (c *CompanyUserController) Put() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.Atoi(idStr) if currentUser.Role != constants.RoleAdmin && id != currentUser.Id { c.ServeJSONError("You can only edit your own userdata!") } v := models.CompanyUser{Id: id} if err := json.Unmarshal(c.Ctx.Input.RequestBody, &v); err == nil { v.ModifiedBy = int64(currentUser.Id) if err := models.UpdateCompanyUserById(o, &v); err == nil { c.ServeJSONSuccess("Ok") } else { c.ServeJSONErrorWithError("Error", err) } } else { c.ServeJSONErrorWithError("Error", err) } c.ServeJSON() } // Delete ... // @Title Delete // @Description delete the CompanyUser // @Param id path string true "The id you want to delete" // @Success 200 {string} delete success! // @Failure 403 id is empty // @router /:id [delete] func (c *CompanyUserController) Delete() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.Atoi(idStr) if currentUser.Role != constants.RoleAdmin && currentUser.Id != id { c.ServeJSONError("You can not delete users other than yourself!") c.ServeJSON() } if currentUser.Role == constants.RoleOwner { c.ServeJSONError("You can not delete users other than yourself!") c.ServeJSON() } uExists, err := models.GetCompanyUserById(o, id) if uExists == nil { c.ServeJSONError("Error: User does not exist!") return } err = models.DeleteCompanyUser(o, id) if err != nil { c.ServeJSONError("Failed to delete company User") } systemDB := companydb.GetSystemDatabase() systemO, err := orm.NewOrmWithDB("postgres", "default", systemDB) // After deleting the user here we need to delete the same User in the system DB userCompanyMapping, err := models.GetUserCompanyMapByCompanyAndCID(systemO, jwtSession.CompanyName, int16(id)) if err != nil { c.ServeJSONError("Error deleting Company User") return } err = models.DeleteUserCompanyMap(systemO, userCompanyMapping.ID) if err != nil { c.ServeJSONError("Error deleting User Company Relation") return } else { c.ServeJSONSuccess("Successfully deleted!") } } // DeleteCompany ... // @Title Delete Company // @Description Delete the entire Company // @Success 200 {string} delete success! // @Failure 403 failed // @router /deletecompany [delete] func (c *CompanyUserController) DeleteCompany() { if currentUser.Role != constants.RoleOwner { c.ServeJSONError("Must be Owner to delete a company") return } systemDB := companydb.GetSystemDatabase() systemO, err := orm.NewOrmWithDB("postgres", "default", systemDB) // first check how many users are left ucm, err := models.GetUserCompanyMapsByCompanyName(systemO, jwtSession.CompanyName) if err != nil { c.ServeJSONError("Error deleting User Company Relation") return } for _, uc := range ucm { systemO.Begin() err = models.DeleteUserCompanyMap(systemO, uc.ID) if err != nil { c.ServeJSONError("Error deleting User Company Relation") systemO.Rollback() return } } // Second check and delete the database err = companydb.DeleteDatabase(jwtSession.CompanyName) if err != nil { systemO.Rollback() c.ServeJSONError("Error deleting Company Database") return } else { systemO.Commit() c.ServeJSONSuccess("Successfully deleted!") } }