1// Copyright 2018 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package etcdserver
16
17import "sync"
18
19// AccessController controls etcd server HTTP request access.
20type AccessController struct {
21	corsMu          sync.RWMutex
22	CORS            map[string]struct{}
23	hostWhitelistMu sync.RWMutex
24	HostWhitelist   map[string]struct{}
25}
26
27// NewAccessController returns a new "AccessController" with default "*" values.
28func NewAccessController() *AccessController {
29	return &AccessController{
30		CORS:          map[string]struct{}{"*": {}},
31		HostWhitelist: map[string]struct{}{"*": {}},
32	}
33}
34
35// OriginAllowed determines whether the server will allow a given CORS origin.
36// If CORS is empty, allow all.
37func (ac *AccessController) OriginAllowed(origin string) bool {
38	ac.corsMu.RLock()
39	defer ac.corsMu.RUnlock()
40	if len(ac.CORS) == 0 { // allow all
41		return true
42	}
43	_, ok := ac.CORS["*"]
44	if ok {
45		return true
46	}
47	_, ok = ac.CORS[origin]
48	return ok
49}
50
51// IsHostWhitelisted returns true if the host is whitelisted.
52// If whitelist is empty, allow all.
53func (ac *AccessController) IsHostWhitelisted(host string) bool {
54	ac.hostWhitelistMu.RLock()
55	defer ac.hostWhitelistMu.RUnlock()
56	if len(ac.HostWhitelist) == 0 { // allow all
57		return true
58	}
59	_, ok := ac.HostWhitelist["*"]
60	if ok {
61		return true
62	}
63	_, ok = ac.HostWhitelist[host]
64	return ok
65}
66