github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/routes/panel/groups.go (about)

     1  package panel
     2  
     3  import (
     4  	"database/sql"
     5  	"net/http"
     6  	"strconv"
     7  	"strings"
     8  
     9  	c "github.com/Azareal/Gosora/common"
    10  	p "github.com/Azareal/Gosora/common/phrases"
    11  )
    12  
    13  func Groups(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
    14  	bPage, ferr := buildBasePage(w, r, u, "groups", "groups")
    15  	if ferr != nil {
    16  		return ferr
    17  	}
    18  	page, _ := strconv.Atoi(r.FormValue("page"))
    19  	perPage := 15
    20  	offset, page, lastPage := c.PageOffset(bPage.Stats.Groups, page, perPage)
    21  
    22  	// Skip the 'Unknown' group
    23  	offset++
    24  
    25  	var count int
    26  	var groupList []c.GroupAdmin
    27  	groups, _ := c.Groups.GetRange(offset, 0)
    28  	for _, g := range groups {
    29  		if count == perPage {
    30  			break
    31  		}
    32  		var rank, rankClass string
    33  		canDelete := false
    34  
    35  		// TODO: Localise this
    36  		switch {
    37  		case g.IsAdmin:
    38  			rank = "Admin"
    39  			rankClass = "admin"
    40  		case g.IsMod:
    41  			rank = "Mod"
    42  			rankClass = "mod"
    43  		case g.IsBanned:
    44  			rank = "Banned"
    45  			rankClass = "banned"
    46  		case g.ID == 6:
    47  			rank = "Guest"
    48  			rankClass = "guest"
    49  		default:
    50  			rank = "Member"
    51  			rankClass = "member"
    52  		}
    53  
    54  		canEdit := u.Perms.EditGroup && (!g.IsAdmin || u.Perms.EditGroupAdmin) && (!g.IsMod || u.Perms.EditGroupSuperMod)
    55  		groupList = append(groupList, c.GroupAdmin{g.ID, g.Name, rank, rankClass, canEdit, canDelete})
    56  		count++
    57  	}
    58  
    59  	pageList := c.Paginate(page, lastPage, 5)
    60  	pi := c.PanelGroupPage{bPage, groupList, c.Paginator{pageList, page, lastPage}}
    61  	return renderTemplate("panel", w, r, bPage.Header, c.Panel{bPage, "", "", "panel_groups", &pi})
    62  }
    63  
    64  func GroupsEdit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
    65  	basePage, ferr := buildBasePage(w, r, user, "edit_group", "groups")
    66  	if ferr != nil {
    67  		return ferr
    68  	}
    69  	if !user.Perms.EditGroup {
    70  		return c.NoPermissions(w, r, user)
    71  	}
    72  
    73  	gid, err := strconv.Atoi(sgid)
    74  	if err != nil {
    75  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
    76  	}
    77  	g, err := c.Groups.Get(gid)
    78  	if err == sql.ErrNoRows {
    79  		//log.Print("aaaaa monsters")
    80  		return c.NotFound(w, r, basePage.Header)
    81  	}
    82  	ferr = groupCheck(w, r, user, g, err)
    83  	if ferr != nil {
    84  		return ferr
    85  	}
    86  
    87  	var rank string
    88  	switch {
    89  	case g.IsAdmin:
    90  		rank = "Admin"
    91  	case g.IsMod:
    92  		rank = "Mod"
    93  	case g.IsBanned:
    94  		rank = "Banned"
    95  	case g.ID == 6:
    96  		rank = "Guest"
    97  	default:
    98  		rank = "Member"
    99  	}
   100  	disableRank := !user.Perms.EditGroupGlobalPerms || (g.ID == 6)
   101  
   102  	pi := c.PanelEditGroupPage{basePage, g.ID, g.Name, g.Tag, rank, disableRank}
   103  	return renderTemplate("panel_group_edit", w, r, basePage.Header, pi)
   104  }
   105  
   106  func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
   107  	basePage, ferr := buildBasePage(w, r, user, "edit_group", "groups")
   108  	if ferr != nil {
   109  		return ferr
   110  	}
   111  	if !user.Perms.EditGroup {
   112  		return c.NoPermissions(w, r, user)
   113  	}
   114  
   115  	gid, err := strconv.Atoi(sgid)
   116  	if err != nil {
   117  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
   118  	}
   119  	g, err := c.Groups.Get(gid)
   120  	if err == sql.ErrNoRows {
   121  		//log.Print("aaaaa monsters")
   122  		return c.NotFound(w, r, basePage.Header)
   123  	}
   124  	ferr = groupCheck(w, r, user, g, err)
   125  	if ferr != nil {
   126  		return ferr
   127  	}
   128  
   129  	promotions, err := c.GroupPromotions.GetByGroup(g.ID)
   130  	if err != sql.ErrNoRows && err != nil {
   131  		return c.InternalError(err, w, r)
   132  	}
   133  	promoteExt := make([]*c.GroupPromotionExtend, len(promotions))
   134  	for i, promote := range promotions {
   135  		fg, err := c.Groups.Get(promote.From)
   136  		if err == sql.ErrNoRows {
   137  			fg = &c.Group{Name: "Deleted Group"}
   138  		} else if err != nil {
   139  			return c.InternalError(err, w, r)
   140  		}
   141  		tg, err := c.Groups.Get(promote.To)
   142  		if err == sql.ErrNoRows {
   143  			tg = &c.Group{Name: "Deleted Group"}
   144  		} else if err != nil {
   145  			return c.InternalError(err, w, r)
   146  		}
   147  		promoteExt[i] = &c.GroupPromotionExtend{promote, fg, tg}
   148  	}
   149  
   150  	// ? - Should we stop admins from deleting all the groups? Maybe, protect the group they're currently using?
   151  	groups, err := c.Groups.GetRange(1, 0) // ? - 0 = Go to the end
   152  	if err != nil {
   153  		return c.InternalError(err, w, r)
   154  	}
   155  
   156  	var groupList []*c.Group
   157  	for _, group := range groups {
   158  		if !user.Perms.EditUserGroupAdmin && group.IsAdmin {
   159  			continue
   160  		}
   161  		if !user.Perms.EditUserGroupSuperMod && group.IsMod {
   162  			continue
   163  		}
   164  		groupList = append(groupList, group)
   165  	}
   166  
   167  	pi := c.PanelEditGroupPromotionsPage{basePage, g.ID, g.Name, promoteExt, groupList}
   168  	return renderTemplate("panel_group_edit_promotions", w, r, basePage.Header, pi)
   169  }
   170  
   171  func groupCheck(w http.ResponseWriter, r *http.Request, u *c.User, g *c.Group, err error) c.RouteError {
   172  	if err == sql.ErrNoRows {
   173  		return c.LocalError("No such group.", w, r, u)
   174  	} else if err != nil {
   175  		return c.InternalError(err, w, r)
   176  	}
   177  	if g.IsAdmin && !u.Perms.EditGroupAdmin {
   178  		return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, u)
   179  	}
   180  	if g.IsMod && !u.Perms.EditGroupSuperMod {
   181  		return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, u)
   182  	}
   183  	return nil
   184  }
   185  
   186  func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User, sgid string) c.RouteError {
   187  	if !u.Perms.EditGroup {
   188  		return c.NoPermissions(w, r, u)
   189  	}
   190  	gid, err := strconv.Atoi(sgid)
   191  	if err != nil {
   192  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
   193  	}
   194  
   195  	from, err := strconv.Atoi(r.FormValue("from"))
   196  	if err != nil {
   197  		return c.LocalError("from must be integer", w, r, u)
   198  	}
   199  	to, err := strconv.Atoi(r.FormValue("to"))
   200  	if err != nil {
   201  		return c.LocalError("to must be integer", w, r, u)
   202  	}
   203  	if from == to {
   204  		return c.LocalError("the from group and to group cannot be the same", w, r, u)
   205  	}
   206  	twoWay := r.FormValue("two-way") == "1"
   207  
   208  	level, err := strconv.Atoi(r.FormValue("level"))
   209  	if err != nil {
   210  		return c.LocalError("level must be integer", w, r, u)
   211  	}
   212  	posts, err := strconv.Atoi(r.FormValue("posts"))
   213  	if err != nil {
   214  		return c.LocalError("posts must be integer", w, r, u)
   215  	}
   216  
   217  	regHours, err := strconv.Atoi(r.FormValue("reg_hours"))
   218  	if err != nil {
   219  		return c.LocalError("reg_hours must be integer", w, r, u)
   220  	}
   221  	regDays, err := strconv.Atoi(r.FormValue("reg_days"))
   222  	if err != nil {
   223  		return c.LocalError("reg_days must be integer", w, r, u)
   224  	}
   225  	regMonths, err := strconv.Atoi(r.FormValue("reg_months"))
   226  	if err != nil {
   227  		return c.LocalError("reg_months must be integer", w, r, u)
   228  	}
   229  	regMinutes := (regHours * 60) + (regDays * 24 * 60) + (regMonths * 30 * 24 * 60)
   230  
   231  	g, err := c.Groups.Get(from)
   232  	ferr := groupCheck(w, r, u, g, err)
   233  	if err != nil {
   234  		return ferr
   235  	}
   236  	g, err = c.Groups.Get(to)
   237  	ferr = groupCheck(w, r, u, g, err)
   238  	if err != nil {
   239  		return ferr
   240  	}
   241  	pid, err := c.GroupPromotions.Create(from, to, twoWay, level, posts, regMinutes)
   242  	if err != nil {
   243  		return c.InternalError(err, w, r)
   244  	}
   245  	err = c.AdminLogs.Create("create", pid, "group_promotion", u.GetIP(), u.ID)
   246  	if err != nil {
   247  		return c.InternalError(err, w, r)
   248  	}
   249  
   250  	http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
   251  	return nil
   252  }
   253  
   254  func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, u *c.User, sspl string) c.RouteError {
   255  	if !u.Perms.EditGroup {
   256  		return c.NoPermissions(w, r, u)
   257  	}
   258  	spl := strings.Split(sspl, "-")
   259  	if len(spl) < 2 {
   260  		return c.LocalError("need two params", w, r, u)
   261  	}
   262  	gid, err := strconv.Atoi(spl[0])
   263  	if err != nil {
   264  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
   265  	}
   266  	pid, err := strconv.Atoi(spl[1])
   267  	if err != nil {
   268  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
   269  	}
   270  
   271  	pro, err := c.GroupPromotions.Get(pid)
   272  	if err == sql.ErrNoRows {
   273  		return c.LocalError("That group promotion doesn't exist", w, r, u)
   274  	} else if err != nil {
   275  		return c.InternalError(err, w, r)
   276  	}
   277  
   278  	g, err := c.Groups.Get(pro.From)
   279  	ferr := groupCheck(w, r, u, g, err)
   280  	if err != nil {
   281  		return ferr
   282  	}
   283  	g, err = c.Groups.Get(pro.To)
   284  	ferr = groupCheck(w, r, u, g, err)
   285  	if err != nil {
   286  		return ferr
   287  	}
   288  	err = c.GroupPromotions.Delete(pid)
   289  	if err != nil {
   290  		return c.InternalError(err, w, r)
   291  	}
   292  	err = c.AdminLogs.Create("delete", pid, "group_promotion", u.GetIP(), u.ID)
   293  	if err != nil {
   294  		return c.InternalError(err, w, r)
   295  	}
   296  
   297  	http.Redirect(w, r, "/panel/groups/edit/promotions/"+strconv.Itoa(gid), http.StatusSeeOther)
   298  	return nil
   299  }
   300  
   301  func GroupsEditPerms(w http.ResponseWriter, r *http.Request, u *c.User, sgid string) c.RouteError {
   302  	basePage, ferr := buildBasePage(w, r, u, "edit_group", "groups")
   303  	if ferr != nil {
   304  		return ferr
   305  	}
   306  	if !u.Perms.EditGroup {
   307  		return c.NoPermissions(w, r, u)
   308  	}
   309  	gid, err := strconv.Atoi(sgid)
   310  	if err != nil {
   311  		return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
   312  	}
   313  
   314  	g, err := c.Groups.Get(gid)
   315  	if err == sql.ErrNoRows {
   316  		//log.Print("aaaaa monsters")
   317  		return c.NotFound(w, r, basePage.Header)
   318  	} else if err != nil {
   319  		return c.InternalError(err, w, r)
   320  	}
   321  	if g.IsAdmin && !u.Perms.EditGroupAdmin {
   322  		return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, u)
   323  	}
   324  	if g.IsMod && !u.Perms.EditGroupSuperMod {
   325  		return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, u)
   326  	}
   327  
   328  	// TODO: Load the phrases in bulk for efficiency?
   329  	var localPerms []c.NameLangToggle
   330  	addPerm := func(permStr string, perm bool) {
   331  		localPerms = append(localPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
   332  	}
   333  
   334  	addPerm("ViewTopic", g.Perms.ViewTopic)
   335  	addPerm("LikeItem", g.Perms.LikeItem)
   336  	addPerm("CreateTopic", g.Perms.CreateTopic)
   337  	//<--
   338  	addPerm("EditTopic", g.Perms.EditTopic)
   339  	addPerm("DeleteTopic", g.Perms.DeleteTopic)
   340  	addPerm("CreateReply", g.Perms.CreateReply)
   341  	addPerm("EditReply", g.Perms.EditReply)
   342  	addPerm("DeleteReply", g.Perms.DeleteReply)
   343  	addPerm("PinTopic", g.Perms.PinTopic)
   344  	addPerm("CloseTopic", g.Perms.CloseTopic)
   345  	addPerm("MoveTopic", g.Perms.MoveTopic)
   346  
   347  	var globalPerms []c.NameLangToggle
   348  	addPerm = func(permStr string, perm bool) {
   349  		globalPerms = append(globalPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
   350  	}
   351  
   352  	addPerm("UploadFiles", g.Perms.UploadFiles)
   353  	addPerm("UploadAvatars", g.Perms.UploadAvatars)
   354  	addPerm("UseConvos", g.Perms.UseConvos)
   355  	addPerm("UseConvosOnlyWithMod", g.Perms.UseConvosOnlyWithMod)
   356  	addPerm("CreateProfileReply", g.Perms.CreateProfileReply)
   357  	addPerm("AutoEmbed", g.Perms.AutoEmbed)
   358  	addPerm("AutoLink", g.Perms.AutoLink)
   359  
   360  	var modPerms []c.NameLangToggle
   361  	addPerm = func(permStr string, perm bool) {
   362  		modPerms = append(modPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm})
   363  	}
   364  
   365  	addPerm("BanUsers", g.Perms.BanUsers)
   366  	addPerm("ActivateUsers", g.Perms.ActivateUsers)
   367  	addPerm("EditUser", g.Perms.EditUser)
   368  	addPerm("EditUserEmail", g.Perms.EditUserEmail)
   369  	addPerm("EditUserPassword", g.Perms.EditUserPassword)
   370  	addPerm("EditUserGroup", g.Perms.EditUserGroup)
   371  	addPerm("EditUserGroupSuperMod", g.Perms.EditUserGroupSuperMod)
   372  	addPerm("EditUserGroupAdmin", g.Perms.EditUserGroupAdmin)
   373  	addPerm("EditGroup", g.Perms.EditGroup)
   374  	addPerm("EditGroupLocalPerms", g.Perms.EditGroupLocalPerms)
   375  	addPerm("EditGroupGlobalPerms", g.Perms.EditGroupGlobalPerms)
   376  	addPerm("EditGroupSuperMod", g.Perms.EditGroupSuperMod)
   377  	addPerm("EditGroupAdmin", g.Perms.EditGroupAdmin)
   378  	addPerm("ManageForums", g.Perms.ManageForums)
   379  	addPerm("EditSettings", g.Perms.EditSettings)
   380  	addPerm("ManageThemes", g.Perms.ManageThemes)
   381  	addPerm("ManagePlugins", g.Perms.ManagePlugins)
   382  	addPerm("ViewAdminLogs", g.Perms.ViewAdminLogs)
   383  	addPerm("ViewIPs", g.Perms.ViewIPs)
   384  
   385  	pi := c.PanelEditGroupPermsPage{basePage, g.ID, g.Name, localPerms, globalPerms, modPerms}
   386  	return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi)
   387  }
   388  
   389  func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
   390  	_, ferr := c.SimplePanelUserCheck(w, r, user)
   391  	if ferr != nil {
   392  		return ferr
   393  	}
   394  	if !user.Perms.EditGroup {
   395  		return c.NoPermissions(w, r, user)
   396  	}
   397  	gid, err := strconv.Atoi(sgid)
   398  	if err != nil {
   399  		return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
   400  	}
   401  	group, err := c.Groups.Get(gid)
   402  	if err == sql.ErrNoRows {
   403  		//log.Print("aaaaa monsters")
   404  		return c.NotFound(w, r, nil)
   405  	}
   406  	ferr = groupCheck(w, r, user, group, err)
   407  	if ferr != nil {
   408  		return ferr
   409  	}
   410  
   411  	name := r.FormValue("name")
   412  	if name == "" {
   413  		return c.LocalError(p.GetErrorPhrase("panel_groups_need_name"), w, r, user)
   414  	}
   415  	tag := r.FormValue("tag")
   416  	rank := r.FormValue("type")
   417  
   418  	var originalRank string
   419  	// TODO: Use a switch for this
   420  	switch {
   421  	case group.IsAdmin:
   422  		originalRank = "Admin"
   423  	case group.IsMod:
   424  		originalRank = "Mod"
   425  	case group.IsBanned:
   426  		originalRank = "Banned"
   427  	case group.ID == 6:
   428  		originalRank = "Guest"
   429  	default:
   430  		originalRank = "Member"
   431  	}
   432  
   433  	if rank != originalRank && originalRank != "Guest" {
   434  		if !user.Perms.EditGroupGlobalPerms {
   435  			return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_group_type"), w, r, user)
   436  		}
   437  		switch rank {
   438  		case "Admin":
   439  			if !user.Perms.EditGroupAdmin {
   440  				return c.LocalError(p.GetErrorPhrase("panel_groups_edit_cannot_designate_admin"), w, r, user)
   441  			}
   442  			err = group.ChangeRank(true, true, false)
   443  		case "Mod":
   444  			if !user.Perms.EditGroupSuperMod {
   445  				return c.LocalError(p.GetErrorPhrase("panel_groups_edit_cannot_designate_supermod"), w, r, user)
   446  			}
   447  			err = group.ChangeRank(false, true, false)
   448  		case "Banned":
   449  			err = group.ChangeRank(false, false, true)
   450  		case "Guest":
   451  			return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_be_guest"), w, r, user)
   452  		case "Member":
   453  			err = group.ChangeRank(false, false, false)
   454  		default:
   455  			return c.LocalError(p.GetErrorPhrase("panel_groups_invalid_group_type"), w, r, user)
   456  		}
   457  		if err != nil {
   458  			return c.InternalError(err, w, r)
   459  		}
   460  	}
   461  
   462  	err = group.Update(name, tag)
   463  	if err != nil {
   464  		return c.InternalError(err, w, r)
   465  	}
   466  	err = c.AdminLogs.Create("edit", group.ID, "group", user.GetIP(), user.ID)
   467  	if err != nil {
   468  		return c.InternalError(err, w, r)
   469  	}
   470  
   471  	http.Redirect(w, r, "/panel/groups/edit/"+strconv.Itoa(gid), http.StatusSeeOther)
   472  	return nil
   473  }
   474  
   475  func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
   476  	_, ferr := c.SimplePanelUserCheck(w, r, user)
   477  	if ferr != nil {
   478  		return ferr
   479  	}
   480  	if !user.Perms.EditGroup {
   481  		return c.NoPermissions(w, r, user)
   482  	}
   483  	gid, err := strconv.Atoi(sgid)
   484  	if err != nil {
   485  		return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
   486  	}
   487  
   488  	group, err := c.Groups.Get(gid)
   489  	if err == sql.ErrNoRows {
   490  		//log.Print("aaaaa monsters o.o")
   491  		return c.NotFound(w, r, nil)
   492  	}
   493  	ferr = groupCheck(w, r, user, group, err)
   494  	if ferr != nil {
   495  		return ferr
   496  	}
   497  
   498  	// TODO: Don't unset perms we don't have permission to set?
   499  	pmap := make(map[string]bool)
   500  	pCheck := func(hasPerm bool, perms []string) {
   501  		if hasPerm {
   502  			for _, perm := range perms {
   503  				pvalue := r.PostFormValue("perm-" + perm)
   504  				pmap[perm] = (pvalue == "1")
   505  			}
   506  		}
   507  	}
   508  	pCheck(user.Perms.EditGroupLocalPerms, c.LocalPermList)
   509  	pCheck(user.Perms.EditGroupGlobalPerms, c.GlobalPermList)
   510  
   511  	err = group.UpdatePerms(pmap)
   512  	if err != nil {
   513  		return c.InternalError(err, w, r)
   514  	}
   515  	err = c.AdminLogs.Create("edit", group.ID, "group", user.GetIP(), user.ID)
   516  	if err != nil {
   517  		return c.InternalError(err, w, r)
   518  	}
   519  
   520  	http.Redirect(w, r, "/panel/groups/edit/perms/"+strconv.Itoa(gid), http.StatusSeeOther)
   521  	return nil
   522  }
   523  
   524  func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
   525  	_, ferr := c.SimplePanelUserCheck(w, r, user)
   526  	if ferr != nil {
   527  		return ferr
   528  	}
   529  	if !user.Perms.EditGroup {
   530  		return c.NoPermissions(w, r, user)
   531  	}
   532  
   533  	name := r.PostFormValue("name")
   534  	if name == "" {
   535  		return c.LocalError(p.GetErrorPhrase("panel_groups_need_name"), w, r, user)
   536  	}
   537  	tag := r.PostFormValue("tag")
   538  
   539  	var admin, mod, banned bool
   540  	if user.Perms.EditGroupGlobalPerms {
   541  		switch r.PostFormValue("type") {
   542  		case "Admin":
   543  			if !user.Perms.EditGroupAdmin {
   544  				return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
   545  			}
   546  			admin = true
   547  			mod = true
   548  		case "Mod":
   549  			if !user.Perms.EditGroupSuperMod {
   550  				return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
   551  			}
   552  			mod = true
   553  		case "Banned":
   554  			banned = true
   555  		}
   556  	}
   557  
   558  	gid, err := c.Groups.Create(name, tag, admin, mod, banned)
   559  	if err != nil {
   560  		return c.InternalError(err, w, r)
   561  	}
   562  	err = c.AdminLogs.Create("create", gid, "group", user.GetIP(), user.ID)
   563  	if err != nil {
   564  		return c.InternalError(err, w, r)
   565  	}
   566  
   567  	http.Redirect(w, r, "/panel/groups/edit/"+strconv.Itoa(gid), http.StatusSeeOther)
   568  	return nil
   569  }