Pull request: all: allow clientid in access settings

Updates #2624.
Updates #3162.

Squashed commit of the following:

commit 68860da717a23a0bfeba14b7fe10b5e4ad38726d
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 29 15:41:33 2021 +0300

    all: imp types, names

commit ebd4ec26636853d0d58c4e331e6a78feede20813
Merge: 239eb721 16e5e09c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 29 15:14:33 2021 +0300

    Merge branch 'master' into 2624-clientid-access

commit 239eb7215abc47e99a0300a0f4cf56002689b1a9
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 29 15:13:10 2021 +0300

    all: fix client blocking check

commit e6bece3ea8367b3cbe3d90702a3368c870ad4f13
Merge: 9935f2a3 9d1656b5
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jun 29 13:12:28 2021 +0300

    Merge branch 'master' into 2624-clientid-access

commit 9935f2a30bcfae2b853f3ef610c0ab7a56a8f448
Author: Ildar Kamalov <ik@adguard.com>
Date:   Tue Jun 29 11:26:51 2021 +0300

    client: show block button for client id

commit ed786a6a74a081cd89e9d67df3537a4fadd54831
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 25 15:56:23 2021 +0300

    client: imp i18n

commit 4fed21c68473ad408960c08a7d87624cabce1911
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 25 15:34:09 2021 +0300

    all: imp i18n, docs

commit 55e65c0d6b939560c53dcb834a4557eb3853d194
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Jun 25 13:34:01 2021 +0300

    all: fix cache, imp code, docs, tests

commit c1e5a83e76deb44b1f92729bb9ddfcc6a96ac4a8
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Thu Jun 24 19:27:12 2021 +0300

    all: allow clientid in access settings
This commit is contained in:
Ainar Garipov
2021-06-29 15:53:28 +03:00
parent 16e5e09c2e
commit e08a64ebe4
33 changed files with 955 additions and 604 deletions

View File

@@ -5,6 +5,8 @@ import (
"fmt"
"net"
"net/http"
"github.com/AdguardTeam/golibs/log"
)
// clientJSON is a common structure used by several handlers to deal with
@@ -44,13 +46,13 @@ type clientJSON struct {
type runtimeClientJSON struct {
WHOISInfo *RuntimeClientWHOISInfo `json:"whois_info"`
IP string `json:"ip"`
Name string `json:"name"`
Source string `json:"source"`
IP net.IP `json:"ip"`
}
type clientListJSON struct {
Clients []clientJSON `json:"clients"`
Clients []*clientJSON `json:"clients"`
RuntimeClients []runtimeClientJSON `json:"auto_clients"`
Tags []string `json:"supported_tags"`
}
@@ -66,11 +68,20 @@ func (clients *clientsContainer) handleGetClients(w http.ResponseWriter, _ *http
cj := clientToJSON(c)
data.Clients = append(data.Clients, cj)
}
for ip, rc := range clients.ipToRC {
clients.ipToRC.Range(func(ip net.IP, v interface{}) (cont bool) {
rc, ok := v.(*RuntimeClient)
if !ok {
log.Error("dns: bad type %T in ipToRC for %s", v, ip)
return true
}
cj := runtimeClientJSON{
IP: ip,
Name: rc.Host,
WHOISInfo: rc.WHOISInfo,
Name: rc.Host,
IP: ip,
}
cj.Source = "etc/hosts"
@@ -86,7 +97,9 @@ func (clients *clientsContainer) handleGetClients(w http.ResponseWriter, _ *http
}
data.RuntimeClients = append(data.RuntimeClients, cj)
}
return true
})
data.Tags = clientTags
@@ -118,8 +131,8 @@ func jsonToClient(cj clientJSON) (c *Client) {
}
// Convert Client object to JSON
func clientToJSON(c *Client) clientJSON {
cj := clientJSON{
func clientToJSON(c *Client) (cj *clientJSON) {
return &clientJSON{
Name: c.Name,
IDs: c.IDs,
Tags: c.Tags,
@@ -134,19 +147,6 @@ func clientToJSON(c *Client) clientJSON {
Upstreams: c.Upstreams,
}
return cj
}
// runtimeClientToJSON converts a RuntimeClient into a JSON struct.
func runtimeClientToJSON(ip string, rc RuntimeClient) (cj clientJSON) {
cj = clientJSON{
Name: rc.Host,
IDs: []string{ip},
WHOISInfo: rc.WHOISInfo,
}
return cj
}
// Add a new client
@@ -230,7 +230,7 @@ func (clients *clientsContainer) handleUpdateClient(w http.ResponseWriter, r *ht
// Get the list of clients by IP address list
func (clients *clientsContainer) handleFindClient(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
data := []map[string]clientJSON{}
data := []map[string]*clientJSON{}
for i := 0; i < len(q); i++ {
idStr := q.Get(fmt.Sprintf("ip%d", i))
if idStr == "" {
@@ -239,20 +239,16 @@ func (clients *clientsContainer) handleFindClient(w http.ResponseWriter, r *http
ip := net.ParseIP(idStr)
c, ok := clients.Find(idStr)
var cj clientJSON
var cj *clientJSON
if !ok {
var found bool
cj, found = clients.findRuntime(ip, idStr)
if !found {
continue
}
cj = clients.findRuntime(ip, idStr)
} else {
cj = clientToJSON(c)
disallowed, rule := clients.dnsServer.IsBlockedIP(ip)
disallowed, rule := clients.dnsServer.IsBlockedClient(ip, idStr)
cj.Disallowed, cj.DisallowedRule = &disallowed, &rule
}
data = append(data, map[string]clientJSON{
data = append(data, map[string]*clientJSON{
idStr: cj,
})
}
@@ -265,39 +261,37 @@ func (clients *clientsContainer) handleFindClient(w http.ResponseWriter, r *http
}
// findRuntime looks up the IP in runtime and temporary storages, like
// /etc/hosts tables, DHCP leases, or blocklists.
func (clients *clientsContainer) findRuntime(ip net.IP, idStr string) (cj clientJSON, found bool) {
if ip == nil {
return cj, false
}
rc, ok := clients.FindRuntimeClient(idStr)
// /etc/hosts tables, DHCP leases, or blocklists. cj is guaranteed to be
// non-nil.
func (clients *clientsContainer) findRuntime(ip net.IP, idStr string) (cj *clientJSON) {
rc, ok := clients.FindRuntimeClient(ip)
if !ok {
// It is still possible that the IP used to be in the runtime
// clients list, but then the server was reloaded. So, check
// the DNS server's blocked IP list.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/2428.
disallowed, rule := clients.dnsServer.IsBlockedIP(ip)
if rule == "" {
return clientJSON{}, false
}
cj = clientJSON{
disallowed, rule := clients.dnsServer.IsBlockedClient(ip, idStr)
cj = &clientJSON{
IDs: []string{idStr},
Disallowed: &disallowed,
DisallowedRule: &rule,
WHOISInfo: &RuntimeClientWHOISInfo{},
}
return cj, true
return cj
}
cj = runtimeClientToJSON(idStr, rc)
disallowed, rule := clients.dnsServer.IsBlockedIP(ip)
cj = &clientJSON{
Name: rc.Host,
IDs: []string{idStr},
WHOISInfo: rc.WHOISInfo,
}
disallowed, rule := clients.dnsServer.IsBlockedClient(ip, idStr)
cj.Disallowed, cj.DisallowedRule = &disallowed, &rule
return cj, true
return cj
}
// RegisterClientsHandlers registers HTTP handlers