<commit_before>package model

import (
	"bytes"
	"database/sql"
	"html/template"
	"net/url"
	"path"
	"regexp"
	"strings"
	"time"

	"reflect"

	"github.com/dgrijalva/jwt-go"
	errors "github.com/tomogoma/go-typed-errors"
	"golang.org/x/crypto/bcrypt"
)

type AuthStore interface {
	IsNotFoundError(error) bool
	ExecuteTx(fn func(*sql.Tx) error) error

	InsertGroup(name string, acl float32) (*Group, error)
	Group(string) (*Group, error)
	GroupByName(string) (*Group, error)

	InsertUserType(name string) (*UserType, error)
	UserTypeByName(string) (*UserType, error)

	HasUsers(groupID string) error
	InsertUserAtomic(tx *sql.Tx, t UserType, password []byte) (*User, error)
	UpdatePassword(userID string, password []byte) error
	UpdatePasswordAtomic(tx *sql.Tx, userID string, password []byte) error
	User(id string) (*User, []byte, error)
	UserByDeviceID(devID string) (*User, []byte, error)
	UserByUsername(username string) (*User, []byte, error)
	UserByPhone(phone string) (*User, []byte, error)
	UserByEmail(email string) (*User, []byte, error)
	UserByFacebook(facebookID string) (*User, error)

	AddUserToGroupAtomic(tx *sql.Tx, userID, groupID string) error

	InsertUserDeviceAtomic(tx *sql.Tx, userID, devID string) (*Device, error)

	InsertUserName(userID, username string) (*Username, error)
	InsertUserNameAtomic(tx *sql.Tx, userID, username string) (*Username, error)

	InsertUserPhone(userID, phone string, verified bool) (*VerifLogin, error)
	InsertUserPhoneAtomic(tx *sql.Tx, userID, phone string, verified bool) (*VerifLogin, error)
	UpdateUserPhone(userID, phone string, verified bool) (*VerifLogin, error)
	UpdateUserPhoneAtomic(tx *sql.Tx, userID, phone string, verified bool) (*VerifLogin, error)

	InsertPhoneToken(userID, phone string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	InsertPhoneTokenAtomic(tx *sql.Tx, userID, phone string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	PhoneTokens(userID string, offset, count int64) ([]DBToken, error)

	InsertUserEmail(userID, email string, verified bool) (*VerifLogin, error)
	InsertUserEmailAtomic(tx *sql.Tx, userID, email string, verified bool) (*VerifLogin, error)
	UpdateUserEmail(userID, email string, verified bool) (*VerifLogin, error)
	UpdateUserEmailAtomic(tx *sql.Tx, userID, email string, verified bool) (*VerifLogin, error)

	InsertEmailToken(userID, email string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	InsertEmailTokenAtomic(tx *sql.Tx, userID, email string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	EmailTokens(userID string, offset, count int64) ([]DBToken, error)

	InsertUserFbIDAtomic(tx *sql.Tx, userID, fbID string, verified bool) (*Facebook, error)
}

type SecureRandomByteser interface {
	SecureRandomBytes(length int) ([]byte, error)
}

type FacebookCl interface {
	IsAuthError(error) bool
	ValidateToken(string) (string, error)
}

type SMSer interface {
	SMS(toPhone, message string) error
}

type JWTEr interface {
	Generate(claims jwt.Claims) (string, error)
	Validate(JWT string, claims jwt.Claims) (*jwt.Token, error)
}

type Mailer interface {
	SendEmail(email SendMail) error
}

// Authentication has the methods for performing auth. Use NewAuthentication()
// to construct.
type Authentication struct {
	errors.AuthErrCheck
	errors.ClErrCheck
	errors.NotImplErrCheck
	errors.NotFoundErrCheck
	// mandatory parameters
	db            AuthStore
	jwter         JWTEr
	passGen       SecureRandomByteser
	numGen        SecureRandomByteser
	urlTokenGen   SecureRandomByteser
	lockDevToUser bool
	allowSelfReg  bool
	// optional parameters
	appNameEmptyable     string
	fbNilable            FacebookCl
	smserNilable         SMSer
	mailerNilable        Mailer
	webAppURLEmptyable   string
	invSubjEmptyable     string
	verSubjEmptyable     string
	resPassSubjEmptyable string
	// tail values optional depending on need/type for communication
	loginTpActionTplts map[string]map[string]*template.Template
}<commit_msg>embed all error checks<commit_after>package model

import (
	"bytes"
	"database/sql"
	"html/template"
	"net/url"
	"path"
	"regexp"
	"strings"
	"time"

	"reflect"

	"github.com/dgrijalva/jwt-go"
	errors "github.com/tomogoma/go-typed-errors"
	"golang.org/x/crypto/bcrypt"
)

type AuthStore interface {
	IsNotFoundError(error) bool
	ExecuteTx(fn func(*sql.Tx) error) error

	InsertGroup(name string, acl float32) (*Group, error)
	Group(string) (*Group, error)
	GroupByName(string) (*Group, error)

	InsertUserType(name string) (*UserType, error)
	UserTypeByName(string) (*UserType, error)

	HasUsers(groupID string) error
	InsertUserAtomic(tx *sql.Tx, t UserType, password []byte) (*User, error)
	UpdatePassword(userID string, password []byte) error
	UpdatePasswordAtomic(tx *sql.Tx, userID string, password []byte) error
	User(id string) (*User, []byte, error)
	UserByDeviceID(devID string) (*User, []byte, error)
	UserByUsername(username string) (*User, []byte, error)
	UserByPhone(phone string) (*User, []byte, error)
	UserByEmail(email string) (*User, []byte, error)
	UserByFacebook(facebookID string) (*User, error)

	AddUserToGroupAtomic(tx *sql.Tx, userID, groupID string) error

	InsertUserDeviceAtomic(tx *sql.Tx, userID, devID string) (*Device, error)

	InsertUserName(userID, username string) (*Username, error)
	InsertUserNameAtomic(tx *sql.Tx, userID, username string) (*Username, error)

	InsertUserPhone(userID, phone string, verified bool) (*VerifLogin, error)
	InsertUserPhoneAtomic(tx *sql.Tx, userID, phone string, verified bool) (*VerifLogin, error)
	UpdateUserPhone(userID, phone string, verified bool) (*VerifLogin, error)
	UpdateUserPhoneAtomic(tx *sql.Tx, userID, phone string, verified bool) (*VerifLogin, error)

	InsertPhoneToken(userID, phone string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	InsertPhoneTokenAtomic(tx *sql.Tx, userID, phone string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	PhoneTokens(userID string, offset, count int64) ([]DBToken, error)

	InsertUserEmail(userID, email string, verified bool) (*VerifLogin, error)
	InsertUserEmailAtomic(tx *sql.Tx, userID, email string, verified bool) (*VerifLogin, error)
	UpdateUserEmail(userID, email string, verified bool) (*VerifLogin, error)
	UpdateUserEmailAtomic(tx *sql.Tx, userID, email string, verified bool) (*VerifLogin, error)

	InsertEmailToken(userID, email string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	InsertEmailTokenAtomic(tx *sql.Tx, userID, email string, dbt []byte, isUsed bool, expiry time.Time) (*DBToken, error)
	EmailTokens(userID string, offset, count int64) ([]DBToken, error)

	InsertUserFbIDAtomic(tx *sql.Tx, userID, fbID string, verified bool) (*Facebook, error)
}

type SecureRandomByteser interface {
	SecureRandomBytes(length int) ([]byte, error)
}

type FacebookCl interface {
	IsAuthError(error) bool
	ValidateToken(string) (string, error)
}

type SMSer interface {
	SMS(toPhone, message string) error
}

type JWTEr interface {
	Generate(claims jwt.Claims) (string, error)
	Validate(JWT string, claims jwt.Claims) (*jwt.Token, error)
}

type Mailer interface {
	SendEmail(email SendMail) error
}

// Authentication has the methods for performing auth. Use NewAuthentication()
// to construct.
type Authentication struct {
	errors.AllErrCheck
	// mandatory parameters
	db            AuthStore
	jwter         JWTEr
	passGen       SecureRandomByteser
	numGen        SecureRandomByteser
	urlTokenGen   SecureRandomByteser
	lockDevToUser bool
	allowSelfReg  bool
	// optional parameters
	appNameEmptyable     string
	fbNilable            FacebookCl
	smserNilable         SMSer
	mailerNilable        Mailer
	webAppURLEmptyable   string
	invSubjEmptyable     string
	verSubjEmptyable     string
	resPassSubjEmptyable string
	// tail values optional depending on need/type for communication
	loginTpActionTplts map[string]map[string]*template.Template
}
{'fraction_non_alphanumeric': 0.10854182461460703, 'fraction_numerical': 0.001516300227445034, 'mean_word_length': 5.546732837055417, 'pattern_counts': {'":': 0, '<': 3, '<?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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '202669', 'n_tokens_mistral': 2630, 'n_tokens_neox': 2584, 'n_words': 718}