github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/group.go (about)

     1  package common
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  
     7  	qgen "github.com/Azareal/Gosora/query_gen"
     8  )
     9  
    10  var blankGroup = Group{ID: 0, Name: ""}
    11  
    12  type GroupAdmin struct {
    13  	ID        int
    14  	Name      string
    15  	Rank      string
    16  	RankClass string
    17  	CanEdit   bool
    18  	CanDelete bool
    19  }
    20  
    21  // ! Fix the data races in the fperms
    22  type Group struct {
    23  	ID              int
    24  	Name            string
    25  	IsMod           bool
    26  	IsAdmin         bool
    27  	IsBanned        bool
    28  	Tag             string
    29  	Perms           Perms
    30  	PermissionsText []byte
    31  	PluginPerms     map[string]bool // Custom permissions defined by plugins. What if two plugins declare the same permission, but they handle them in incompatible ways? Very unlikely, we probably don't need to worry about this, the plugin authors should be aware of each other to some extent
    32  	PluginPermsText []byte
    33  	CanSee          []int // The IDs of the forums this group can see
    34  	UserCount       int   // ! Might be temporary as I might want to lean on the database instead for this
    35  }
    36  
    37  type GroupStmts struct {
    38  	updateGroup      *sql.Stmt
    39  	updateGroupRank  *sql.Stmt
    40  	updateGroupPerms *sql.Stmt
    41  }
    42  
    43  var groupStmts GroupStmts
    44  
    45  func init() {
    46  	DbInits.Add(func(acc *qgen.Accumulator) error {
    47  		set := func(s string) *sql.Stmt {
    48  			return acc.Update("users_groups").Set(s).Where("gid=?").Prepare()
    49  		}
    50  		groupStmts = GroupStmts{
    51  			updateGroup:      set("name=?,tag=?"),
    52  			updateGroupRank:  set("is_admin=?,is_mod=?,is_banned=?"),
    53  			updateGroupPerms: set("permissions=?"),
    54  		}
    55  		return acc.FirstError()
    56  	})
    57  }
    58  
    59  func (g *Group) ChangeRank(isAdmin, isMod, isBanned bool) (err error) {
    60  	_, err = groupStmts.updateGroupRank.Exec(isAdmin, isMod, isBanned, g.ID)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	_ = Groups.Reload(g.ID)
    65  	return nil
    66  }
    67  
    68  func (g *Group) Update(name, tag string) (err error) {
    69  	_, err = groupStmts.updateGroup.Exec(name, tag, g.ID)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	_ = Groups.Reload(g.ID)
    74  	return nil
    75  }
    76  
    77  // Please don't pass arbitrary inputs to this method
    78  func (g *Group) UpdatePerms(perms map[string]bool) (err error) {
    79  	pjson, err := json.Marshal(perms)
    80  	if err != nil {
    81  		return err
    82  	}
    83  	_, err = groupStmts.updateGroupPerms.Exec(pjson, g.ID)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	return Groups.Reload(g.ID)
    88  }
    89  
    90  // Copy gives you a non-pointer concurrency safe copy of the group
    91  func (g *Group) Copy() Group {
    92  	return *g
    93  }
    94  
    95  func (g *Group) CopyPtr() (co *Group) {
    96  	co = new(Group)
    97  	*co = *g
    98  	return co
    99  }
   100  
   101  // TODO: Replace this sorting mechanism with something a lot more efficient
   102  // ? - Use sort.Slice instead?
   103  type SortGroup []*Group
   104  
   105  func (sg SortGroup) Len() int {
   106  	return len(sg)
   107  }
   108  func (sg SortGroup) Swap(i, j int) {
   109  	sg[i], sg[j] = sg[j], sg[i]
   110  }
   111  func (sg SortGroup) Less(i, j int) bool {
   112  	return sg[i].ID < sg[j].ID
   113  }