podman
91 строка · 2.7 Кб
1// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
2// Use of this source code is governed by a MIT style
3// license that can be found in the LICENSE file.
4
5package gin6
7import (8"crypto/subtle"9"encoding/base64"10"net/http"11"strconv"12
13"github.com/gin-gonic/gin/internal/bytesconv"14)
15
16// AuthUserKey is the cookie name for user credential in basic auth.
17const AuthUserKey = "user"18
19// Accounts defines a key/value for user/pass list of authorized logins.
20type Accounts map[string]string21
22type authPair struct {23value string24user string25}
26
27type authPairs []authPair28
29func (a authPairs) searchCredential(authValue string) (string, bool) {30if authValue == "" {31return "", false32}33for _, pair := range a {34if subtle.ConstantTimeCompare(bytesconv.StringToBytes(pair.value), bytesconv.StringToBytes(authValue)) == 1 {35return pair.user, true36}37}38return "", false39}
40
41// BasicAuthForRealm returns a Basic HTTP Authorization middleware. It takes as arguments a map[string]string where
42// the key is the user name and the value is the password, as well as the name of the Realm.
43// If the realm is empty, "Authorization Required" will be used by default.
44// (see http://tools.ietf.org/html/rfc2617#section-1.2)
45func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {46if realm == "" {47realm = "Authorization Required"48}49realm = "Basic realm=" + strconv.Quote(realm)50pairs := processAccounts(accounts)51return func(c *Context) {52// Search user in the slice of allowed credentials53user, found := pairs.searchCredential(c.requestHeader("Authorization"))54if !found {55// Credentials doesn't match, we return 401 and abort handlers chain.56c.Header("WWW-Authenticate", realm)57c.AbortWithStatus(http.StatusUnauthorized)58return59}60
61// The user credentials was found, set user's id to key AuthUserKey in this context, the user's id can be read later using62// c.MustGet(gin.AuthUserKey).63c.Set(AuthUserKey, user)64}65}
66
67// BasicAuth returns a Basic HTTP Authorization middleware. It takes as argument a map[string]string where
68// the key is the user name and the value is the password.
69func BasicAuth(accounts Accounts) HandlerFunc {70return BasicAuthForRealm(accounts, "")71}
72
73func processAccounts(accounts Accounts) authPairs {74length := len(accounts)75assert1(length > 0, "Empty list of authorized credentials")76pairs := make(authPairs, 0, length)77for user, password := range accounts {78assert1(user != "", "User can not be empty")79value := authorizationHeader(user, password)80pairs = append(pairs, authPair{81value: value,82user: user,83})84}85return pairs86}
87
88func authorizationHeader(user, password string) string {89base := user + ":" + password90return "Basic " + base64.StdEncoding.EncodeToString(bytesconv.StringToBytes(base))91}
92