<commit_before>package genericsite

// OK, only user-related stuff, 23-03-13

import (
	"crypto/sha256"
	"errors"
	"io"
	"math/rand"
	"strings"
	"time"

	. "github.com/xyproto/browserspeak"
	"github.com/xyproto/web"
)

type UserState struct {
	// see: http://redis.io/topics/data-types
	users       *RedisHashMap   // Hash map of users, with several different fields per user ("loggedin", "confirmed", "email" etc)
	usernames   *RedisSet       // A list of all usernames, for easy enumeration
	unconfirmed *RedisSet       // A list of unconfirmed usernames, for easy enumeration
	pool        *ConnectionPool // A connection pool for Redis
}

// An Engine is a specific piece of a website
// This part handles the login/logout/registration/confirmation pages

type UserEngine Engine

const (
	ONLY_LOGIN      = "100"
	ONLY_LOGOUT     = "010"
	ONLY_REGISTER   = "001"
	EXCEPT_LOGIN    = "011"
	EXCEPT_LOGOUT   = "101"
	EXCEPT_REGISTER = "110"
	NOTHING         = "000"

	MINIMUM_CONFIRMATION_CODE_LENGTH = 20
	USERNAME_ALLOWED_LETTERS         = "abcdefghijklmnopqrstuvwxyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ_0123456789"
)

func (state *UserState) GetPool() *ConnectionPool {
	return state.pool
}

func NewUserEngine(state *UserState) *UserEngine {
	return &UserEngine{state}
}

func InitUserSystem(pool *ConnectionPool) *UserState {

	// For the secure cookies
	// This must happen before the random seeding, or 
	// else people will have to log in again after every server restart
	web.Config.CookieSecret = RandomCookieFriendlyString(30)

	rand.Seed(time.Now().UnixNano())

	return createUserState(pool)
}

// Checks if the current user is logged in as a user right now
func (state *UserState) UserRights(ctx *web.Context) bool {
	if username := GetBrowserUsername(ctx); username != "" {
		return state.IsLoggedIn(username)
	}
	return false
}<commit_msg>Menus are weird, stop using urls to fetch them<commit_after>package genericsite

// OK, only user-related stuff, 23-03-13

import (
	"crypto/sha256"
	"errors"
	"io"
	"math/rand"
	"strings"
	"time"

	. "github.com/xyproto/browserspeak"
	"github.com/xyproto/web"
)

type UserState struct {
	// see: http://redis.io/topics/data-types
	users       *RedisHashMap   // Hash map of users, with several different fields per user ("loggedin", "confirmed", "email" etc)
	usernames   *RedisSet       // A list of all usernames, for easy enumeration
	unconfirmed *RedisSet       // A list of unconfirmed usernames, for easy enumeration
	pool        *ConnectionPool // A connection pool for Redis
}

// An Engine is a specific piece of a website
// This part handles the login/logout/registration/confirmation pages

// TODO: Engine should be an interface, not a type
type UserEngine Engine

const (
	ONLY_LOGIN      = "100"
	ONLY_LOGOUT     = "010"
	ONLY_REGISTER   = "001"
	EXCEPT_LOGIN    = "011"
	EXCEPT_LOGOUT   = "101"
	EXCEPT_REGISTER = "110"
	NOTHING         = "000"

	MINIMUM_CONFIRMATION_CODE_LENGTH = 20
	USERNAME_ALLOWED_LETTERS         = "abcdefghijklmnopqrstuvwxyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ_0123456789"
)

// Optimized function for login, logout and register
func HideIfNotLoginLogoutRegister(threeBooleanURL, logintag, logouttag, registertag string) string {
	src := "$.get(" + quote(threeBooleanURL) + ", function(data) {"
	// TODO: See what happens if data < 3 length
	src += "if (data[0] != \"1\") {" + Hide(logintag) + "};"
	src += "if (data[1] != \"1\") {" + Hide(logouttag) + "};"
	src += "if (data[2] != \"1\") {" + Hide(registertag) + "};"
	src += "});"
	return src
}

// Optimized function for login, logout and register
func ShowIfLoginLogoutRegister(threeBooleanURL, logintag, logouttag, registertag string) string {
	src := "$.get(" + quote(threeBooleanURL) + ", function(data) {"
	// TODO: See what happens if data < 3 length
	src += "if (data[0] == \"1\") {" + ShowInlineAnimated(logintag) + "};"
	src += "if (data[1] == \"1\") {" + ShowInlineAnimated(logouttag) + "};"
	src += "if (data[2] == \"1\") {" + ShowInlineAnimated(registertag) + "};"
	src += "});"
	return src
}

func (state *UserState) GetPool() *ConnectionPool {
	return state.pool
}

func NewUserEngine(state *UserState) *UserEngine {
	return &UserEngine{state}
}

func InitUserSystem(pool *ConnectionPool) *UserState {

	// For the secure cookies
	// This must happen before the random seeding, or 
	// else people will have to log in again after every server restart
	web.Config.CookieSecret = RandomCookieFriendlyString(30)

	rand.Seed(time.Now().UnixNano())

	return createUserState(pool)
}

// Checks if the current user is logged in as a user right now
func (state *UserState) UserRights(ctx *web.Context) bool {
	if username := GetBrowserUsername(ctx); username != "" {
		return state.IsLoggedIn(username)
	}
	return false
}
{'fraction_non_alphanumeric': 0.12146003775959723, 'fraction_numerical': 0.021397105097545627, 'mean_word_length': 3.9307135470527403, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6148685', 'n_tokens_mistral': 1717, 'n_tokens_neox': 1620, 'n_words': 453}