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

     1  package routes
     2  
     3  import (
     4  	"database/sql"
     5  	"net/http"
     6  	"strconv"
     7  	"time"
     8  
     9  	c "github.com/Azareal/Gosora/common"
    10  )
    11  
    12  func BanUserSubmit(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
    13  	if !u.Perms.BanUsers {
    14  		return c.NoPermissions(w, r, u)
    15  	}
    16  	uid, err := strconv.Atoi(suid)
    17  	if err != nil {
    18  		return c.LocalError("The provided UserID is not a valid number.", w, r, u)
    19  	}
    20  	if uid == -2 {
    21  		return c.LocalError("Why don't you like Merlin?", w, r, u)
    22  	}
    23  
    24  	targetUser, err := c.Users.Get(uid)
    25  	if err == sql.ErrNoRows {
    26  		return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
    27  	} else if err != nil {
    28  		return c.InternalError(err, w, r)
    29  	}
    30  	// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
    31  	if targetUser.IsMod {
    32  		return c.LocalError("You may not ban another staff member.", w, r, u)
    33  	}
    34  	if uid == u.ID {
    35  		return c.LocalError("Why are you trying to ban yourself? Stop that.", w, r, u)
    36  	}
    37  	if targetUser.IsBanned {
    38  		return c.LocalError("The user you're trying to unban is already banned.", w, r, u)
    39  	}
    40  
    41  	durDays, err := strconv.Atoi(r.FormValue("dur-days"))
    42  	if err != nil {
    43  		return c.LocalError("You can only use whole numbers for the number of days", w, r, u)
    44  	}
    45  	durWeeks, err := strconv.Atoi(r.FormValue("dur-weeks"))
    46  	if err != nil {
    47  		return c.LocalError("You can only use whole numbers for the number of weeks", w, r, u)
    48  	}
    49  	durMonths, err := strconv.Atoi(r.FormValue("dur-months"))
    50  	if err != nil {
    51  		return c.LocalError("You can only use whole numbers for the number of months", w, r, u)
    52  	}
    53  	deletePosts := false
    54  	switch r.FormValue("delete-posts") {
    55  	case "1":
    56  		deletePosts = true
    57  	}
    58  
    59  	var dur time.Duration
    60  	if durDays > 1 && durWeeks > 1 && durMonths > 1 {
    61  		dur, _ = time.ParseDuration("0")
    62  	} else {
    63  		var secs int
    64  		secs += durDays * int(c.Day)
    65  		secs += durWeeks * int(c.Week)
    66  		secs += durMonths * int(c.Month)
    67  		dur, _ = time.ParseDuration(strconv.Itoa(secs) + "s")
    68  	}
    69  
    70  	err = targetUser.Ban(dur, u.ID)
    71  	if err == sql.ErrNoRows {
    72  		return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
    73  	} else if err != nil {
    74  		return c.InternalError(err, w, r)
    75  	}
    76  	err = c.ModLogs.Create("ban", uid, "user", u.GetIP(), u.ID)
    77  	if err != nil {
    78  		return c.InternalError(err, w, r)
    79  	}
    80  
    81  	if deletePosts {
    82  		err = targetUser.DeletePosts()
    83  		if err == sql.ErrNoRows {
    84  			return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
    85  		} else if err != nil {
    86  			return c.InternalError(err, w, r)
    87  		}
    88  		err = c.ModLogs.Create("delete-posts", uid, "user", u.GetIP(), u.ID)
    89  		if err != nil {
    90  			return c.InternalError(err, w, r)
    91  		}
    92  	}
    93  
    94  	// TODO: Trickle the hookTable down from the router
    95  	hTbl := c.GetHookTable()
    96  	skip, rerr := hTbl.VhookSkippable("action_end_ban_user", targetUser.ID, u)
    97  	if skip || rerr != nil {
    98  		return rerr
    99  	}
   100  
   101  	http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
   102  	return nil
   103  }
   104  
   105  func UnbanUser(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
   106  	if !u.Perms.BanUsers {
   107  		return c.NoPermissions(w, r, u)
   108  	}
   109  	uid, err := strconv.Atoi(suid)
   110  	if err != nil {
   111  		return c.LocalError("The provided UserID is not a valid number.", w, r, u)
   112  	}
   113  
   114  	targetUser, err := c.Users.Get(uid)
   115  	if err == sql.ErrNoRows {
   116  		return c.LocalError("The user you're trying to unban no longer exists.", w, r, u)
   117  	} else if err != nil {
   118  		return c.InternalError(err, w, r)
   119  	}
   120  	if !targetUser.IsBanned {
   121  		return c.LocalError("The user you're trying to unban isn't banned.", w, r, u)
   122  	}
   123  
   124  	err = targetUser.Unban()
   125  	if err == c.ErrNoTempGroup {
   126  		return c.LocalError("The user you're trying to unban is not banned", w, r, u)
   127  	} else if err == sql.ErrNoRows {
   128  		return c.LocalError("The user you're trying to unban no longer exists.", w, r, u)
   129  	} else if err != nil {
   130  		return c.InternalError(err, w, r)
   131  	}
   132  
   133  	err = c.ModLogs.Create("unban", uid, "user", u.GetIP(), u.ID)
   134  	if err != nil {
   135  		return c.InternalError(err, w, r)
   136  	}
   137  
   138  	// TODO: Trickle the hookTable down from the router
   139  	hTbl := c.GetHookTable()
   140  	skip, rerr := hTbl.VhookSkippable("action_end_unban_user", targetUser.ID, u)
   141  	if skip || rerr != nil {
   142  		return rerr
   143  	}
   144  
   145  	http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
   146  	return nil
   147  }
   148  
   149  func ActivateUser(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
   150  	if !u.Perms.ActivateUsers {
   151  		return c.NoPermissions(w, r, u)
   152  	}
   153  	uid, err := strconv.Atoi(suid)
   154  	if err != nil {
   155  		return c.LocalError("The provided UserID is not a valid number.", w, r, u)
   156  	}
   157  
   158  	targetUser, err := c.Users.Get(uid)
   159  	if err == sql.ErrNoRows {
   160  		return c.LocalError("The account you're trying to activate no longer exists.", w, r, u)
   161  	} else if err != nil {
   162  		return c.InternalError(err, w, r)
   163  	}
   164  	if targetUser.Active {
   165  		return c.LocalError("The account you're trying to activate has already been activated.", w, r, u)
   166  	}
   167  	err = targetUser.Activate()
   168  	if err != nil {
   169  		return c.InternalError(err, w, r)
   170  	}
   171  
   172  	targetUser, err = c.Users.Get(uid)
   173  	if err == sql.ErrNoRows {
   174  		return c.LocalError("The account you're trying to activate no longer exists.", w, r, u)
   175  	} else if err != nil {
   176  		return c.InternalError(err, w, r)
   177  	}
   178  	err = c.GroupPromotions.PromoteIfEligible(targetUser, targetUser.Level, targetUser.Posts, targetUser.CreatedAt)
   179  	if err != nil {
   180  		return c.InternalError(err, w, r)
   181  	}
   182  	targetUser.CacheRemove()
   183  
   184  	err = c.ModLogs.Create("activate", targetUser.ID, "user", u.GetIP(), u.ID)
   185  	if err != nil {
   186  		return c.InternalError(err, w, r)
   187  	}
   188  
   189  	// TODO: Trickle the hookTable down from the router
   190  	hTbl := c.GetHookTable()
   191  	skip, rerr := hTbl.VhookSkippable("action_end_activate_user", targetUser.ID, u)
   192  	if skip || rerr != nil {
   193  		return rerr
   194  	}
   195  
   196  	http.Redirect(w, r, "/user/"+strconv.Itoa(targetUser.ID), http.StatusSeeOther)
   197  	return nil
   198  }
   199  
   200  func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
   201  	if !u.Perms.BanUsers {
   202  		return c.NoPermissions(w, r, u)
   203  	}
   204  	uid, err := strconv.Atoi(suid)
   205  	if err != nil {
   206  		return c.LocalError("The provided UserID is not a valid number.", w, r, u)
   207  	}
   208  
   209  	targetUser, err := c.Users.Get(uid)
   210  	if err == sql.ErrNoRows {
   211  		return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, u)
   212  	} else if err != nil {
   213  		return c.InternalError(err, w, r)
   214  	}
   215  	// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
   216  	if targetUser.IsMod {
   217  		return c.LocalError("You may not purge the posts of another staff member.", w, r, u)
   218  	}
   219  
   220  	err = targetUser.DeletePosts()
   221  	if err == sql.ErrNoRows {
   222  		return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, u)
   223  	} else if err != nil {
   224  		return c.InternalError(err, w, r)
   225  	}
   226  	err = c.ModLogs.Create("delete-posts", uid, "user", u.GetIP(), u.ID)
   227  	if err != nil {
   228  		return c.InternalError(err, w, r)
   229  	}
   230  
   231  	// TODO: Trickle the hookTable down from the router
   232  	hTbl := c.GetHookTable()
   233  	skip, rerr := hTbl.VhookSkippable("action_end_delete_posts", targetUser.ID, u)
   234  	if skip || rerr != nil {
   235  		return rerr
   236  	}
   237  
   238  	http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
   239  	return nil
   240  }