123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- package common
- import (
- "database/sql"
- "devel.mephi.ru/dyokunev/cps-api/app/common/db"
- models "devel.mephi.ru/dyokunev/cps-models"
- acdir "devel.mephi.ru/dyokunev/go-acdir"
- asuModels "devel.mephi.ru/dyokunev/go-asu-models"
- helpers "devel.mephi.ru/dyokunev/go-helpers"
- mysqlDriver "github.com/go-sql-driver/mysql"
- "github.com/revel/revel"
- "strconv"
- "strings"
- "sync"
- "time"
- )
- type Permissions struct {
- IsFixOk bool
- IsFullAccess bool
- IsVoip bool
- HeadedUnits asuModels.Units
- AllowedUnits asuModels.Units
- AllowedPeople asuModels.People
- }
- var (
- userInfoMap = map[string]UserInfo{}
- userInfoMapMutex = &sync.Mutex{}
- getUserInfoMutex = &sync.Mutex{}
- )
- func InitUserInfo() {
- go func() {
- for {
- userInfoMapMutex.Lock()
- userInfoMap = map[string]UserInfo{}
- userInfoMapMutex.Unlock()
- time.Sleep(time.Minute * 5)
- }
- }()
- }
- func DownloadUserInfo(username string) UserInfo {
- var info UserInfo
- info.Username = strings.ToLower(username)
- ldapEntry, err := acdir.GetEntryByUsername(username)
- if err == nil {
- if ldapEntry.EmpGUID == 0 {
- //panic("ldapEntry.EmpGUID == 0")
- return info
- }
- info.EmpGUID = ldapEntry.EmpGUID
- info.Permissions.HeadedUnits = asuModels.GetUnitsHeadedBy(info.EmpGUID)
- info.Permissions.HeadedUnits.DoRecursive(func(unit *asuModels.Unit, argI interface{}) bool {
- info.Permissions.AllowedUnits = append(info.Permissions.AllowedUnits, *unit)
- return true
- }, nil)
- info.Permissions.AllowedPeople = info.Permissions.AllowedUnits.PrepareFormulars(true, false).GetFormulars().PreparePeople().GetPeople()
- me, err := asuModels.PersonSQL.First(asuModels.Person{EmpGUID: info.EmpGUID})
- if err != nil {
- panic(err)
- }
- info.Permissions.AllowedPeople = append(info.Permissions.AllowedPeople, me)
- } else {
- if err != acdir.ErrNoRows {
- panic(err)
- }
- }
- cpsUser, err := models.CpsUserSQL.First(models.CpsUser{Username: username})
- for err == mysqlDriver.ErrInvalidConn { // TODO: remove this hacky workaround. ATM, it solved floating bug: "invalid connection"
- cpsUser, err = models.CpsUserSQL.First(models.CpsUser{Username: username})
- }
- if err != nil && err != sql.ErrNoRows {
- panic(err)
- }
- if err == nil {
- info.Permissions = AppendPermissions(cpsUser, info.Permissions)
- }
- // Checking if the user has full access. In this case it's recommended to disable filters in app/controllers/controller.go:Controller.init()
- {
- rows, err := db.Sdapi1Raw.Query("SELECT COUNT(*) FROM unit")
- if err != nil {
- panic(err)
- }
- defer rows.Close()
- if !rows.Next() {
- panic("This shouldn't happend")
- }
- var unitsCount int
- err = rows.Scan(&unitsCount)
- if err != nil {
- panic(err)
- }
- if len(info.Permissions.AllowedUnits) > unitsCount {
- panic("This shouldn't happend")
- }
- if len(info.Permissions.AllowedUnits) == unitsCount {
- info.Permissions.IsFullAccess = true
- }
- }
- return info
- }
- func GetUserInfo(username string) UserInfo {
- getUserInfoMutex.Lock()
- defer func() { getUserInfoMutex.Unlock() }()
- username = strings.ToLower(username)
- userInfoMapMutex.Lock()
- info := userInfoMap[username]
- userInfoMapMutex.Unlock()
- if info.Username != username {
- info = DownloadUserInfo(username)
- userInfoMapMutex.Lock()
- userInfoMap[username] = info
- userInfoMapMutex.Unlock()
- }
- return info
- }
- func AppendPermissions(cpsUser models.CpsUser, permissions Permissions) Permissions {
- alreadySetUnitIds := map[int]bool{}
- for _, unit := range permissions.AllowedUnits {
- alreadySetUnitIds[unit.Id] = true
- }
- if cpsUser.UnitCodePatternsStr != nil {
- *cpsUser.UnitCodePatternsStr = strings.Replace(helpers.RemoveAllStringByPattern(*cpsUser.UnitCodePatternsStr, "[^0-9%*]+"), "*", "%", -1)
- if len(*cpsUser.UnitCodePatternsStr) > 0 {
- unitCodePatterns := strings.Split(*cpsUser.UnitCodePatternsStr, ",")
- for _, pattern := range unitCodePatterns {
- if pattern == "%" {
- var err error
- permissions.AllowedUnits, err = asuModels.UnitSQL.Select()
- if err != nil {
- panic(err)
- }
- permissions.AllowedPeople, err = asuModels.PersonSQL.Select()
- if err != nil {
- panic(err)
- }
- continue
- }
- pattern = "1" + pattern
- var units asuModels.Units
- units, err := asuModels.UnitSQL.ActiveOnly().Select("Code LIKE ?", pattern)
- if err != nil {
- panic(err)
- }
- units.PrepareChildrenTree().DoRecursive(func(unit *asuModels.Unit, argI interface{}) bool {
- if alreadySetUnitIds[unit.Id] {
- return true
- }
- permissions.AllowedUnits = append(permissions.AllowedUnits, *unit)
- permissions.AllowedPeople = append(permissions.AllowedPeople, unit.PrepareFormulars().GetFormulars().PreparePeople().GetPeople()...)
- return true
- }, nil)
- }
- }
- }
- for _, unit := range permissions.AllowedUnits {
- alreadySetUnitIds[unit.Id] = true
- }
- if cpsUser.EmpGUIDsStr != nil {
- *cpsUser.EmpGUIDsStr = helpers.RemoveAllStringByPattern(*cpsUser.EmpGUIDsStr, "[^0-9]+")
- if len(*cpsUser.EmpGUIDsStr) > 0 {
- EmpGUIDsS := strings.Split(*cpsUser.EmpGUIDsStr, ",")
- for _, empGUIDS := range EmpGUIDsS {
- empGUID, err := strconv.Atoi(empGUIDS)
- if err != nil {
- panic(err)
- }
- person, err := asuModels.PersonSQL.First(asuModels.Person{EmpGUID: empGUID})
- if err == sql.ErrNoRows {
- revel.WARN.Printf("Cannot find person with EmpGUID == %v", empGUID)
- continue
- }
- if err != nil {
- panic(nil)
- }
- permissions.AllowedPeople = append(permissions.AllowedPeople, person)
- }
- }
- }
- permissions.AllowedPeople = permissions.AllowedPeople.Deduplicate()
- return permissions
- }
- func (p Permissions) GetShortForm() map[string]interface{} {
- permissions := map[string]interface{}{}
- permissions["isFullAccess"] = p.IsFullAccess
- permissions["isFixOk"] = p.IsFixOk
- if !p.IsFullAccess {
- var allowedUnits []map[string]interface{}
- for _, allowedUnit := range p.AllowedUnits {
- allowedUnits = append(allowedUnits, map[string]interface{}{
- "id": allowedUnit.Id,
- "code": allowedUnit.Code,
- "persNumber": allowedUnit.PersNumber,
- })
- }
- permissions["allowedUnits"] = allowedUnits
- permissions["allowedPeople"] = p.AllowedPeople.GetEmpGUIDs()
- }
- return permissions
- }
|