podman

Форк
0
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

5
package gin
6

7
import (
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.
17
const AuthUserKey = "user"
18

19
// Accounts defines a key/value for user/pass list of authorized logins.
20
type Accounts map[string]string
21

22
type authPair struct {
23
	value string
24
	user  string
25
}
26

27
type authPairs []authPair
28

29
func (a authPairs) searchCredential(authValue string) (string, bool) {
30
	if authValue == "" {
31
		return "", false
32
	}
33
	for _, pair := range a {
34
		if subtle.ConstantTimeCompare(bytesconv.StringToBytes(pair.value), bytesconv.StringToBytes(authValue)) == 1 {
35
			return pair.user, true
36
		}
37
	}
38
	return "", false
39
}
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)
45
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {
46
	if realm == "" {
47
		realm = "Authorization Required"
48
	}
49
	realm = "Basic realm=" + strconv.Quote(realm)
50
	pairs := processAccounts(accounts)
51
	return func(c *Context) {
52
		// Search user in the slice of allowed credentials
53
		user, found := pairs.searchCredential(c.requestHeader("Authorization"))
54
		if !found {
55
			// Credentials doesn't match, we return 401 and abort handlers chain.
56
			c.Header("WWW-Authenticate", realm)
57
			c.AbortWithStatus(http.StatusUnauthorized)
58
			return
59
		}
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 using
62
		// c.MustGet(gin.AuthUserKey).
63
		c.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.
69
func BasicAuth(accounts Accounts) HandlerFunc {
70
	return BasicAuthForRealm(accounts, "")
71
}
72

73
func processAccounts(accounts Accounts) authPairs {
74
	length := len(accounts)
75
	assert1(length > 0, "Empty list of authorized credentials")
76
	pairs := make(authPairs, 0, length)
77
	for user, password := range accounts {
78
		assert1(user != "", "User can not be empty")
79
		value := authorizationHeader(user, password)
80
		pairs = append(pairs, authPair{
81
			value: value,
82
			user:  user,
83
		})
84
	}
85
	return pairs
86
}
87

88
func authorizationHeader(user, password string) string {
89
	base := user + ":" + password
90
	return "Basic " + base64.StdEncoding.EncodeToString(bytesconv.StringToBytes(base))
91
}
92

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.