...

Source file src/codeberg.org/tslocum/sriracha/internal/server/server_ban.go

Documentation: codeberg.org/tslocum/sriracha/internal/server

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"log"
     7  	"net/http"
     8  	"regexp"
     9  	"strings"
    10  
    11  	"codeberg.org/tslocum/sriracha/internal/database"
    12  	. "codeberg.org/tslocum/sriracha/model"
    13  	. "codeberg.org/tslocum/sriracha/util"
    14  )
    15  
    16  func (s *Server) loadBanForm(db *database.DB, r *http.Request, b *Ban) {
    17  	b.Expire = FormInt64(r, "expire")
    18  	b.Reason = FormString(r, "reason")
    19  }
    20  
    21  func (s *Server) serveBan(data *templateData, db *database.DB, w http.ResponseWriter, r *http.Request) {
    22  	data.Template = "manage_ban"
    23  	data.Boards = db.AllBoards()
    24  
    25  	deleteBanID := PathInt(r, "/sriracha/ban/delete/")
    26  	if deleteBanID > 0 {
    27  		if s.forbidden(w, data, "ban.delete") {
    28  			return
    29  		}
    30  		b := db.BanByID(deleteBanID)
    31  		if b == nil {
    32  			data.ManageError("Invalid ban.")
    33  			return
    34  		}
    35  		db.DeleteBan(b.ID)
    36  
    37  		if strings.HasPrefix(b.IP, "r ") {
    38  			s.reloadBans(db)
    39  		}
    40  
    41  		var changes string
    42  		liftReason := FormString(r, "reason")
    43  		if strings.TrimSpace(liftReason) != "" {
    44  			changes = "Reason: " + liftReason
    45  		}
    46  
    47  		s.log(db, data.Account, nil, fmt.Sprintf("Lifted ban #%d", b.ID), changes)
    48  
    49  		http.Redirect(w, r, "/sriracha/ban/", http.StatusFound)
    50  		return
    51  	}
    52  
    53  	banID := PathInt(r, "/sriracha/ban/")
    54  	if banID > 0 {
    55  		data.Manage.Ban = db.BanByID(banID)
    56  
    57  		if data.Manage.Ban != nil && r.Method == http.MethodPost {
    58  			oldBan := *data.Manage.Ban
    59  			s.loadBanForm(db, r, data.Manage.Ban)
    60  
    61  			shorter := data.Manage.Ban.Expire != 0 && (oldBan.Expire == 0 || data.Manage.Ban.Expire < oldBan.Expire)
    62  			if shorter && s.forbidden(w, data, "ban.shorten") {
    63  				return
    64  			} else if !shorter && s.forbidden(w, data, "ban.lengthen") {
    65  				return
    66  			}
    67  
    68  			err := data.Manage.Ban.Validate()
    69  			if err != nil {
    70  				data.ManageError(err.Error())
    71  				return
    72  			}
    73  
    74  			db.UpdateBan(data.Manage.Ban)
    75  
    76  			if strings.HasPrefix(data.Manage.Ban.IP, "r ") {
    77  				s.reloadBans(db)
    78  			}
    79  
    80  			changes := printChanges(oldBan, *data.Manage.Ban)
    81  			s.log(db, data.Account, nil, fmt.Sprintf("Updated >>/ban/%d", data.Manage.Ban.ID), changes)
    82  
    83  			http.Redirect(w, r, "/sriracha/ban/", http.StatusFound)
    84  			return
    85  		}
    86  		return
    87  	}
    88  
    89  	if r.Method == http.MethodPost {
    90  		r.ParseForm()
    91  		f, _, err := r.FormFile("liftfile")
    92  		if err == nil && f != nil {
    93  			if s.forbidden(w, data, "banfile.delete") {
    94  				return
    95  			}
    96  			buf, err := io.ReadAll(f)
    97  			if err != nil {
    98  				log.Fatal(err)
    99  			}
   100  			hash := calculateFileHash(buf)
   101  			if db.FileBanned(hash) {
   102  				db.LiftFileBan(hash)
   103  				data.Info = "Lifted file ban."
   104  				s.log(db, data.Account, nil, "Lifted file ban", "")
   105  			} else {
   106  				data.ManageError("File is not banned.")
   107  			}
   108  			return
   109  		} else if s.forbidden(w, data, "ban.add") {
   110  			return
   111  		}
   112  
   113  		b := &Ban{}
   114  		s.loadBanForm(db, r, b)
   115  
   116  		ip := FormString(r, "ip")
   117  		if strings.ContainsRune(ip, '*') {
   118  			pattern := strings.ReplaceAll(strings.ReplaceAll(ip, ".", `\.`), "*", ".*")
   119  			_, err := regexp.Compile(pattern)
   120  			if err != nil {
   121  				data.ManageError(fmt.Sprintf("failed to compile ban `%s` as regular expression: %s", pattern, err))
   122  				return
   123  			}
   124  			b.IP = "r " + pattern
   125  		} else if ip != "" {
   126  			b.IP = s._hashIP(ip)
   127  		}
   128  
   129  		err = b.Validate()
   130  		if err != nil {
   131  			data.ManageError(err.Error())
   132  			return
   133  		}
   134  
   135  		match := db.BanByIP(b.IP)
   136  		if match != nil {
   137  			data.ManageError("A ban for that IP address or range already exists.")
   138  			return
   139  		}
   140  
   141  		db.AddBan(b)
   142  
   143  		if strings.HasPrefix(b.IP, "r ") {
   144  			s.reloadBans(db)
   145  		}
   146  
   147  		s.log(db, data.Account, nil, fmt.Sprintf("Added >>/ban/%d", b.ID), b.Info())
   148  
   149  		http.Redirect(w, r, "/sriracha/ban/", http.StatusFound)
   150  		return
   151  	}
   152  
   153  	data.Manage.Bans = db.AllBans(false)
   154  }
   155  

View as plain text