From e1d6eaade158ed48d9abe8de46ab7703581f1645 Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期五, 17 五月 2024 16:40:18 +0800
Subject: [PATCH] 修复videoLabel没有设备id的bug
---
pkg/auth/basic.go | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/pkg/auth/basic.go b/pkg/auth/basic.go
new file mode 100644
index 0000000..f328a32
--- /dev/null
+++ b/pkg/auth/basic.go
@@ -0,0 +1,161 @@
+package auth
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha1"
+ "crypto/subtle"
+ "encoding/base64"
+ "errors"
+ "net/http"
+ "strings"
+
+ "golang.org/x/crypto/bcrypt"
+)
+
+type compareFunc func(hashedPassword, password []byte) error
+
+var (
+ errMismatchedHashAndPassword = errors.New("mismatched hash and password")
+
+ compareFuncs = []struct {
+ prefix string
+ compare compareFunc
+ }{
+ {"", compareMD5HashAndPassword}, // default compareFunc
+ {"{SHA}", compareShaHashAndPassword},
+ // Bcrypt is complicated. According to crypt(3) from
+ // crypt_blowfish version 1.3 (fetched from
+ // http://www.openwall.com/crypt/crypt_blowfish-1.3.tar.gz), there
+ // are three different has prefixes: "$2a$", used by versions up
+ // to 1.0.4, and "$2x$" and "$2y$", used in all later
+ // versions. "$2a$" has a known bug, "$2x$" was added as a
+ // migration path for systems with "$2a$" prefix and still has a
+ // bug, and only "$2y$" should be used by modern systems. The bug
+ // has something to do with handling of 8-bit characters. Since
+ // both "$2a$" and "$2x$" are deprecated, we are handling them the
+ // same way as "$2y$", which will yield correct results for 7-bit
+ // character passwords, but is wrong for 8-bit character
+ // passwords. You have to upgrade to "$2y$" if you want sant 8-bit
+ // character password support with bcrypt. To add to the mess,
+ // OpenBSD 5.5. introduced "$2b$" prefix, which behaves exactly
+ // like "$2y$" according to the same source.
+ {"$2a$", bcrypt.CompareHashAndPassword},
+ {"$2b$", bcrypt.CompareHashAndPassword},
+ {"$2x$", bcrypt.CompareHashAndPassword},
+ {"$2y$", bcrypt.CompareHashAndPassword},
+ }
+)
+
+// BasicAuth is an authenticator implementation for 'Basic' HTTP
+// Authentication scheme (RFC 7617).
+type BasicAuth struct {
+ Realm string
+ Secrets SecretProvider
+ // Headers used by authenticator. Set to ProxyHeaders to use with
+ // proxy server. When nil, NormalHeaders are used.
+ Headers *Headers
+}
+
+// check that BasicAuth implements AuthenticatorInterface
+var _ = (AuthenticatorInterface)((*BasicAuth)(nil))
+
+// CheckAuth checks the username/password combination from the
+// request. Returns either an empty string (authentication failed) or
+// the name of the authenticated user.
+func (a *BasicAuth) CheckAuth(r *http.Request) string {
+ user, password, ok := r.BasicAuth()
+ if !ok {
+ return ""
+ }
+
+ secret := a.Secrets(user, a.Realm)
+ if secret == "" {
+ return ""
+ }
+
+ if !CheckSecret(password, secret) {
+ return ""
+ }
+
+ return user
+}
+
+// CheckSecret returns true if the password matches the encrypted
+// secret.
+func CheckSecret(password, secret string) bool {
+ compare := compareFuncs[0].compare
+ for _, cmp := range compareFuncs[1:] {
+ if strings.HasPrefix(secret, cmp.prefix) {
+ compare = cmp.compare
+ break
+ }
+ }
+ return compare([]byte(secret), []byte(password)) == nil
+}
+
+func compareShaHashAndPassword(hashedPassword, password []byte) error {
+ d := sha1.New()
+ d.Write(password)
+ if subtle.ConstantTimeCompare(hashedPassword[5:], []byte(base64.StdEncoding.EncodeToString(d.Sum(nil)))) != 1 {
+ return errMismatchedHashAndPassword
+ }
+ return nil
+}
+
+func compareMD5HashAndPassword(hashedPassword, password []byte) error {
+ parts := bytes.SplitN(hashedPassword, []byte("$"), 4)
+ if len(parts) != 4 {
+ return errMismatchedHashAndPassword
+ }
+ magic := []byte("$" + string(parts[1]) + "$")
+ salt := parts[2]
+ if subtle.ConstantTimeCompare(hashedPassword, MD5Crypt(password, salt, magic)) != 1 {
+ return errMismatchedHashAndPassword
+ }
+ return nil
+}
+
+// RequireAuth is an http.HandlerFunc for BasicAuth which initiates
+// the authentication process (or requires reauthentication).
+func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set(contentType, a.Headers.V().UnauthContentType)
+ w.Header().Set(a.Headers.V().Authenticate, `Basic realm="`+a.Realm+`"`)
+ w.WriteHeader(a.Headers.V().UnauthCode)
+ w.Write([]byte(a.Headers.V().UnauthResponse))
+}
+
+// Wrap returns an http.HandlerFunc, which wraps
+// AuthenticatedHandlerFunc with this BasicAuth authenticator's
+// authentication checks. Once the request contains valid credentials,
+// it calls wrapped AuthenticatedHandlerFunc.
+//
+// Deprecated: new code should use NewContext instead.
+func (a *BasicAuth) Wrap(wrapped AuthenticatedHandlerFunc) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if username := a.CheckAuth(r); username == "" {
+ a.RequireAuth(w, r)
+ } else {
+ ar := &AuthenticatedRequest{Request: *r, Username: username}
+ wrapped(w, ar)
+ }
+ }
+}
+
+// NewContext returns a context carrying authentication information for the request.
+func (a *BasicAuth) NewContext(ctx context.Context, r *http.Request) context.Context {
+ info := &Info{Username: a.CheckAuth(r), ResponseHeaders: make(http.Header)}
+ info.Authenticated = (info.Username != "")
+ if !info.Authenticated {
+ info.ResponseHeaders.Set(a.Headers.V().Authenticate, `Basic realm="`+a.Realm+`"`)
+ }
+ return context.WithValue(ctx, infoKey, info)
+}
+
+// NewBasicAuthenticator returns a BasicAuth initialized with provided
+// realm and secrets.
+//
+// Deprecated: new code should construct BasicAuth values directly.
+func NewBasicAuthenticator(realm string, secrets SecretProvider) *BasicAuth {
+ return &BasicAuth{Realm: realm, Secrets: secrets}
+}
--
Gitblit v1.8.0