1 Star 0 Fork 0

Ragus/gost

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
auth.go 2.86 KB
一键复制 编辑 原始数据 按行查看 历史
ginuerzh 提交于 2019-06-03 16:14 . fix HTTP Host header
package gost
import (
"bufio"
"io"
"strings"
"sync"
"time"
)
// Authenticator is an interface for user authentication.
type Authenticator interface {
Authenticate(user, password string) bool
}
// LocalAuthenticator is an Authenticator that authenticates client by local key-value pairs.
type LocalAuthenticator struct {
kvs map[string]string
period time.Duration
stopped chan struct{}
mux sync.RWMutex
}
// NewLocalAuthenticator creates an Authenticator that authenticates client by local infos.
func NewLocalAuthenticator(kvs map[string]string) *LocalAuthenticator {
return &LocalAuthenticator{
kvs: kvs,
stopped: make(chan struct{}),
}
}
// Authenticate checks the validity of the provided user-password pair.
func (au *LocalAuthenticator) Authenticate(user, password string) bool {
if au == nil {
return true
}
au.mux.RLock()
defer au.mux.RUnlock()
if len(au.kvs) == 0 {
return true
}
v, ok := au.kvs[user]
return ok && (v == "" || password == v)
}
// Add adds a key-value pair to the Authenticator.
func (au *LocalAuthenticator) Add(k, v string) {
au.mux.Lock()
defer au.mux.Unlock()
if au.kvs == nil {
au.kvs = make(map[string]string)
}
au.kvs[k] = v
}
// Reload parses config from r, then live reloads the Authenticator.
func (au *LocalAuthenticator) Reload(r io.Reader) error {
var period time.Duration
kvs := make(map[string]string)
if r == nil || au.Stopped() {
return nil
}
// splitLine splits a line text by white space.
// A line started with '#' will be ignored, otherwise it is valid.
split := func(line string) []string {
if line == "" {
return nil
}
line = strings.Replace(line, "\t", " ", -1)
line = strings.TrimSpace(line)
if strings.IndexByte(line, '#') == 0 {
return nil
}
var ss []string
for _, s := range strings.Split(line, " ") {
if s = strings.TrimSpace(s); s != "" {
ss = append(ss, s)
}
}
return ss
}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
ss := split(line)
if len(ss) == 0 {
continue
}
switch ss[0] {
case "reload": // reload option
if len(ss) > 1 {
period, _ = time.ParseDuration(ss[1])
}
default:
var k, v string
k = ss[0]
if len(ss) > 1 {
v = ss[1]
}
kvs[k] = v
}
}
if err := scanner.Err(); err != nil {
return err
}
au.mux.Lock()
defer au.mux.Unlock()
au.period = period
au.kvs = kvs
return nil
}
// Period returns the reload period.
func (au *LocalAuthenticator) Period() time.Duration {
if au.Stopped() {
return -1
}
au.mux.RLock()
defer au.mux.RUnlock()
return au.period
}
// Stop stops reloading.
func (au *LocalAuthenticator) Stop() {
select {
case <-au.stopped:
default:
close(au.stopped)
}
}
// Stopped checks whether the reloader is stopped.
func (au *LocalAuthenticator) Stopped() bool {
select {
case <-au.stopped:
return true
default:
return false
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ragus/gost.git
git@gitee.com:ragus/gost.git
ragus
gost
gost
master

搜索帮助