diff options
author | Vidhu Kant Sharma <bokuwakanojogahoshii@yahoo.com> | 2020-10-19 11:05:36 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <bokuwakanojogahoshii@yahoo.com> | 2020-10-19 11:05:36 +0530 |
commit | 9c2ad91230d72fe6d661450cc78300ea223ae2bc (patch) | |
tree | 17bd774b3f972359dfbb46248f085bbf1c6dae98 /vendor/github.com/gin-gonic/gin/auth.go |
make it better
Diffstat (limited to 'vendor/github.com/gin-gonic/gin/auth.go')
-rw-r--r-- | vendor/github.com/gin-gonic/gin/auth.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/vendor/github.com/gin-gonic/gin/auth.go b/vendor/github.com/gin-gonic/gin/auth.go new file mode 100644 index 0000000..33f8e9a --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/auth.go @@ -0,0 +1,98 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "crypto/subtle" + "encoding/base64" + "strconv" +) + +const ( + AuthUserKey = "user" +) + +type ( + Accounts map[string]string + authPair struct { + Value string + User string + } + authPairs []authPair +) + +func (a authPairs) searchCredential(authValue string) (string, bool) { + if len(authValue) == 0 { + return "", false + } + for _, pair := range a { + if pair.Value == authValue { + return pair.User, true + } + } + return "", false +} + +// Implements a basic Basic HTTP Authorization. It takes as arguments a map[string]string where +// the key is the user name and the value is the password, as well as the name of the Realm +// (see http://tools.ietf.org/html/rfc2617#section-1.2) +func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc { + if realm == "" { + realm = "Authorization Required" + } + realm = "Basic realm=" + strconv.Quote(realm) + pairs := processAccounts(accounts) + return func(c *Context) { + // Search user in the slice of allowed credentials + user, found := pairs.searchCredential(c.Request.Header.Get("Authorization")) + if !found { + // Credentials doesn't match, we return 401 and abort handlers chain. + c.Header("WWW-Authenticate", realm) + c.AbortWithStatus(401) + } else { + // The user credentials was found, set user's id to key AuthUserKey in this context, the userId can be read later using + // c.MustGet(gin.AuthUserKey) + c.Set(AuthUserKey, user) + } + } +} + +// Implements a basic Basic HTTP Authorization. It takes as argument a map[string]string where +// the key is the user name and the value is the password. +func BasicAuth(accounts Accounts) HandlerFunc { + return BasicAuthForRealm(accounts, "") +} + +func processAccounts(accounts Accounts) authPairs { + if len(accounts) == 0 { + panic("Empty list of authorized credentials") + } + pairs := make(authPairs, 0, len(accounts)) + for user, password := range accounts { + if len(user) == 0 { + panic("User can not be empty") + } + value := authorizationHeader(user, password) + pairs = append(pairs, authPair{ + Value: value, + User: user, + }) + } + return pairs +} + +func authorizationHeader(user, password string) string { + base := user + ":" + password + return "Basic " + base64.StdEncoding.EncodeToString([]byte(base)) +} + +func secureCompare(given, actual string) bool { + if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 { + return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1 + } else { + /* Securely compare actual to itself to keep constant time, but always return false */ + return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false + } +} |