all: imp code
This commit is contained in:
parent
2dd1c94123
commit
7bf8f0a516
|
@ -435,25 +435,30 @@ func (clients *clientsContainer) handleFindClient(w http.ResponseWriter, r *http
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, _ := netip.ParseAddr(idStr)
|
|
||||||
c, ok := clients.storage.Find(idStr)
|
|
||||||
var cj *clientJSON
|
|
||||||
if !ok {
|
|
||||||
cj = clients.findRuntime(ip, idStr)
|
|
||||||
} else {
|
|
||||||
cj = clientToJSON(c)
|
|
||||||
disallowed, rule := clients.clientChecker.IsBlockedClient(ip, idStr)
|
|
||||||
cj.Disallowed, cj.DisallowedRule = &disallowed, &rule
|
|
||||||
}
|
|
||||||
|
|
||||||
data = append(data, map[string]*clientJSON{
|
data = append(data, map[string]*clientJSON{
|
||||||
idStr: cj,
|
idStr: clients.findClient(idStr),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
aghhttp.WriteJSONResponseOK(w, r, data)
|
aghhttp.WriteJSONResponseOK(w, r, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findClient returns available information about a client by idStr from the
|
||||||
|
// client's storage or access settings. cj is guaranteed to be non-nil.
|
||||||
|
func (clients *clientsContainer) findClient(idStr string) (cj *clientJSON) {
|
||||||
|
ip, _ := netip.ParseAddr(idStr)
|
||||||
|
c, ok := clients.storage.Find(idStr)
|
||||||
|
if !ok {
|
||||||
|
return clients.findRuntime(ip, idStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cj = clientToJSON(c)
|
||||||
|
disallowed, rule := clients.clientChecker.IsBlockedClient(ip, idStr)
|
||||||
|
cj.Disallowed, cj.DisallowedRule = &disallowed, &rule
|
||||||
|
|
||||||
|
return cj
|
||||||
|
}
|
||||||
|
|
||||||
// searchQueryJSON is a request to the POST /control/clients/search HTTP API.
|
// searchQueryJSON is a request to the POST /control/clients/search HTTP API.
|
||||||
//
|
//
|
||||||
// TODO(s.chzhen): Add UIDs.
|
// TODO(s.chzhen): Add UIDs.
|
||||||
|
@ -480,19 +485,12 @@ func (clients *clientsContainer) handleSearchClient(w http.ResponseWriter, r *ht
|
||||||
data := []map[string]*clientJSON{}
|
data := []map[string]*clientJSON{}
|
||||||
for _, c := range q.Clients {
|
for _, c := range q.Clients {
|
||||||
idStr := c.ID
|
idStr := c.ID
|
||||||
ip, _ := netip.ParseAddr(idStr)
|
if idStr == "" {
|
||||||
c, ok := clients.storage.Find(idStr)
|
break
|
||||||
var cj *clientJSON
|
|
||||||
if !ok {
|
|
||||||
cj = clients.findRuntime(ip, idStr)
|
|
||||||
} else {
|
|
||||||
cj = clientToJSON(c)
|
|
||||||
disallowed, rule := clients.clientChecker.IsBlockedClient(ip, idStr)
|
|
||||||
cj.Disallowed, cj.DisallowedRule = &disallowed, &rule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = append(data, map[string]*clientJSON{
|
data = append(data, map[string]*clientJSON{
|
||||||
idStr: cj,
|
idStr: clients.findClient(idStr),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/client"
|
"github.com/AdguardTeam/AdGuardHome/internal/client"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/schedule"
|
"github.com/AdguardTeam/AdGuardHome/internal/schedule"
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/whois"
|
||||||
"github.com/AdguardTeam/golibs/testutil"
|
"github.com/AdguardTeam/golibs/testutil"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -410,10 +411,28 @@ func TestClientsContainer_HandleFindClient(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
|
var (
|
||||||
|
runtimeCli = "runtime_client1"
|
||||||
|
|
||||||
|
runtimeCliIP = "3.3.3.3"
|
||||||
|
blockedCliIP = "4.4.4.4"
|
||||||
|
nonExistentCliIP = "5.5.5.5"
|
||||||
|
|
||||||
|
allowed = false
|
||||||
|
dissallowed = true
|
||||||
|
|
||||||
|
emptyRule = ""
|
||||||
|
disallowedRule = "disallowed_rule"
|
||||||
|
)
|
||||||
|
|
||||||
clients := newClientsContainer(t)
|
clients := newClientsContainer(t)
|
||||||
clients.clientChecker = &testBlockedClientChecker{
|
clients.clientChecker = &testBlockedClientChecker{
|
||||||
onIsBlockedClient: func(ip netip.Addr, clientID string) (ok bool, rule string) {
|
onIsBlockedClient: func(ip netip.Addr, _ string) (ok bool, rule string) {
|
||||||
return false, ""
|
if ip == netip.MustParseAddr(blockedCliIP) {
|
||||||
|
return true, disallowedRule
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, emptyRule
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,11 +448,13 @@ func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
|
|
||||||
assertPersistentClients(t, clients, []*client.Persistent{clientOne, clientTwo})
|
assertPersistentClients(t, clients, []*client.Persistent{clientOne, clientTwo})
|
||||||
|
|
||||||
|
clients.UpdateAddress(ctx, netip.MustParseAddr(runtimeCliIP), runtimeCli, nil)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
query *searchQueryJSON
|
query *searchQueryJSON
|
||||||
wantCode int
|
wantPersistent []*client.Persistent
|
||||||
wantClient []*client.Persistent
|
wantRuntime *clientJSON
|
||||||
}{{
|
}{{
|
||||||
name: "single",
|
name: "single",
|
||||||
query: &searchQueryJSON{
|
query: &searchQueryJSON{
|
||||||
|
@ -441,8 +462,7 @@ func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
ID: testClientIP1,
|
ID: testClientIP1,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
wantCode: http.StatusOK,
|
wantPersistent: []*client.Persistent{clientOne},
|
||||||
wantClient: []*client.Persistent{clientOne},
|
|
||||||
}, {
|
}, {
|
||||||
name: "multiple",
|
name: "multiple",
|
||||||
query: &searchQueryJSON{
|
query: &searchQueryJSON{
|
||||||
|
@ -452,8 +472,47 @@ func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
ID: testClientIP2,
|
ID: testClientIP2,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
wantCode: http.StatusOK,
|
wantPersistent: []*client.Persistent{clientOne, clientTwo},
|
||||||
wantClient: []*client.Persistent{clientOne, clientTwo},
|
}, {
|
||||||
|
name: "runtime",
|
||||||
|
query: &searchQueryJSON{
|
||||||
|
Clients: []searchClientJSON{{
|
||||||
|
ID: runtimeCliIP,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
wantRuntime: &clientJSON{
|
||||||
|
Name: runtimeCli,
|
||||||
|
IDs: []string{runtimeCliIP},
|
||||||
|
Disallowed: &allowed,
|
||||||
|
DisallowedRule: &emptyRule,
|
||||||
|
WHOIS: &whois.Info{},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "blocked_access",
|
||||||
|
query: &searchQueryJSON{
|
||||||
|
Clients: []searchClientJSON{{
|
||||||
|
ID: blockedCliIP,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
wantRuntime: &clientJSON{
|
||||||
|
IDs: []string{blockedCliIP},
|
||||||
|
Disallowed: &dissallowed,
|
||||||
|
DisallowedRule: &disallowedRule,
|
||||||
|
WHOIS: &whois.Info{},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "non_existing_client",
|
||||||
|
query: &searchQueryJSON{
|
||||||
|
Clients: []searchClientJSON{{
|
||||||
|
ID: nonExistentCliIP,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
wantRuntime: &clientJSON{
|
||||||
|
IDs: []string{nonExistentCliIP},
|
||||||
|
Disallowed: &allowed,
|
||||||
|
DisallowedRule: &emptyRule,
|
||||||
|
WHOIS: &whois.Info{},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
@ -469,7 +528,7 @@ func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
rw := httptest.NewRecorder()
|
rw := httptest.NewRecorder()
|
||||||
clients.handleSearchClient(rw, r)
|
clients.handleSearchClient(rw, r)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tc.wantCode, rw.Code)
|
require.Equal(t, http.StatusOK, rw.Code)
|
||||||
|
|
||||||
body, err = io.ReadAll(rw.Body)
|
body, err = io.ReadAll(rw.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -478,7 +537,17 @@ func TestClientsContainer_HandleSearchClient(t *testing.T) {
|
||||||
err = json.Unmarshal(body, &clientData)
|
err = json.Unmarshal(body, &clientData)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assertPersistentClientsData(t, clients, clientData, tc.wantClient)
|
if tc.wantPersistent != nil {
|
||||||
|
assertPersistentClientsData(t, clients, clientData, tc.wantPersistent)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Len(t, clientData, 1)
|
||||||
|
require.Len(t, clientData[0], 1)
|
||||||
|
|
||||||
|
rc := clientData[0][tc.wantRuntime.IDs[0]]
|
||||||
|
assert.Equal(t, tc.wantRuntime, rc)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
|
|
||||||
### New client APIs
|
### New client APIs
|
||||||
|
|
||||||
* The new `POST /control/clients/search` HTTP API allows config updates.
|
* The new `POST /control/clients/search` HTTP API allows config updates. It
|
||||||
|
accepts a JSON object with the following format:
|
||||||
These APIs accept and return a JSON object with the following format:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|
|
@ -2779,8 +2779,8 @@
|
||||||
'clients':
|
'clients':
|
||||||
'type': 'array'
|
'type': 'array'
|
||||||
'items':
|
'items':
|
||||||
'$ref': '#/components/schemas/ClientsIDEntry'
|
'$ref': '#/components/schemas/ClientsSearchRequestItem'
|
||||||
'ClientsIDEntry':
|
'ClientsSearchRequestItem':
|
||||||
'type': 'object'
|
'type': 'object'
|
||||||
'properties':
|
'properties':
|
||||||
'id':
|
'id':
|
||||||
|
|
Loading…
Reference in New Issue