pull out of older repos

This commit is contained in:
Risotto Bias 2025-01-12 04:40:15 -07:00
parent e3ea2dcbf1
commit 78f9e9b3f1
13 changed files with 218 additions and 8 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

29
auth_check.go Normal file
View file

@ -0,0 +1,29 @@
package csrf
import (
"crypto/md5"
"fmt"
"strconv"
"time"
)
// authenticated routes
// compare two. possibly change this into middleware?
func (c CSRF) AuthCheck(userID string, routeName string, givenToken string) bool {
minfactor := strconv.Itoa(time.Now().Hour())
minfactor_1 := strconv.Itoa(time.Now().Hour() - 1)
comp := fmt.Sprintf("%x", md5.Sum([]byte(userID+routeName+c.CSRFKey+minfactor)))
comp2 := fmt.Sprintf("%x", md5.Sum([]byte(userID+routeName+c.CSRFKey+minfactor_1)))
// comp := sha256.New()
// comp.Write([]byte(userID + routeName + CSRFKey + strconv.Itoa(time.Now().Hour())))
// be charitable:
//comp2 := sha256.New()
//comp2.Write([]byte(userID + routeName + CSRFKey + strconv.Itoa(time.Now().Hour()-1)))
if comp == givenToken {
return true
}
// second comparison for last hour:
return comp2 == givenToken
//return fmt.Sprintf("%x", comp2.Sum(nil)) == givenToken
}

18
auth_make.go Normal file
View file

@ -0,0 +1,18 @@
package csrf
import (
"crypto/md5"
"fmt"
"strconv"
"time"
)
// a CSRF key is valid for the current time, route, and user.
func (c CSRF) AuthMake(userID string, routeName string) string {
// h := sha256.New()
// h.Write([]byte(userID + routeName + CSRFKey + strconv.Itoa(time.Now().Hour())))
// return fmt.Sprintf("%x", h.Sum(nil))
minfactor := strconv.Itoa(time.Now().Hour())
res := fmt.Sprintf("%x", md5.Sum([]byte(userID+routeName+c.CSRFKey+minfactor)))
return res
}

23
example_test.go Normal file
View file

@ -0,0 +1,23 @@
package csrf_test
import (
"fmt"
"net/http"
"git.bivouac.wiki/use/csrf"
)
func denied(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Println("404: " + r.URL.Path)
w.WriteHeader(403)
w.Write([]byte("CSRF invalid"))
}
func ExampleCSRF() {
k := csrf.SessionRandB64(16)
c := csrf.New(k, denied)
val := c.AuthMake("alice", "/home")
c.AuthCheck("alice", "/home", val)
// can add in the httptest examples for the middleware in a bit.
}

View file

@ -1 +0,0 @@
package csrf

View file

@ -1,3 +0,0 @@
package csrf
// guest routes

23
init.go Normal file
View file

@ -0,0 +1,23 @@
package csrf
import "net/http"
type CSRF struct {
CSRFKey string
DeniedFn DenyFN
}
type DenyFN func(w http.ResponseWriter, r *http.Request)
// NewCSRFRand makes a new CSRF with a random key.
func NewRand(deniedfn DenyFN) CSRF {
k := SessionRandB64(16)
return New(k, deniedfn)
}
// NewCSRF creates a CSRF with a defined key
func New(key string, deniedfn DenyFN) CSRF {
return CSRF{
CSRFKey: key,
DeniedFn: deniedfn,
}
}

View file

@ -1 +1,29 @@
package csrf package csrf
import "net/http"
type CtxKey string
const ContextUserId CtxKey = "userid"
func (c CSRF) MiddleAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// requires WhoIsThis middleware to set this context key beforehand...
userID := r.Context().Value(ContextUserId).(string)
if c.AuthCheck(userID, r.RequestURI, r.FormValue("csrf")) {
c.DeniedFn(w, r)
return
}
next.ServeHTTP(w, r)
})
}
func (c CSRF) MiddleUnauth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !c.UnauthCheck(r.RequestURI, r.FormValue("csrf")) {
c.DeniedFn(w, r)
return
}
next.ServeHTTP(w, r)
})
}

28
rand.go Normal file
View file

@ -0,0 +1,28 @@
package csrf
import (
"crypto/rand"
"encoding/base64"
"fmt"
"math"
)
func urlRandomBase64String(l int) string {
buff := make([]byte, int(math.Ceil(float64(l)/float64(1.33333333333))))
rand.Read(buff)
str := base64.RawURLEncoding.EncodeToString(buff)
return str[:l] // strip 1 extra character we get from odd length results
}
func randChars(len int) []byte {
val := make([]byte, len)
if _, err := rand.Read(val); err != nil {
fmt.Println(err)
}
return val
}
func SessionRandB64(len int) string {
val := randChars(len)
res := base64.StdEncoding.EncodeToString(val)
return res
}

28
unauth_check.go Normal file
View file

@ -0,0 +1,28 @@
package csrf
import (
"crypto/md5"
"fmt"
"strconv"
"time"
)
// guest routes
func (c CSRF) UnauthCheck(routename string, givenToken string) bool {
//comp := sha256.New()
minfactor := strconv.Itoa(time.Now().Minute() / 10)
minfactor_1 := strconv.Itoa((time.Now().Minute() / 10) - 1)
comp := fmt.Sprintf("%x", md5.Sum([]byte(routename+c.CSRFKey+minfactor)))
//comp.Write([]byte(routename + CSRFKey + minfactor))
// be charitable:
comp2 := fmt.Sprintf("%x", md5.Sum([]byte(routename+c.CSRFKey+minfactor_1)))
// comp2 := sha256.New()
// comp2.Write([]byte(routename + CSRFKey + minfactor_1))
if comp == givenToken {
return true
}
// second comparison for last hour:
return comp2 == givenToken
//return fmt.Sprintf("%x", comp2.Sum(nil)) == givenToken
}

20
unauth_make.go Normal file
View file

@ -0,0 +1,20 @@
package csrf
import (
"crypto/md5"
"fmt"
"strconv"
"time"
)
// userless CSRF
func (c CSRF) UnauthMake(routename string) string {
//shorter time scales
// h := sha256.New()
// get time in 10 minute chunks
minfactor := strconv.Itoa(time.Now().Minute() / 10)
res := fmt.Sprintf("%x", md5.Sum([]byte(routename+c.CSRFKey+minfactor)))
// h.Write([]byte(routename + CSRFKey + minfactor))
// res := fmt.Sprintf("%x", h.Sum(nil))
return res
}

View file

@ -1 +0,0 @@
package csrf

View file

@ -1,3 +0,0 @@
package csrf
// authenticated routes