diff --git a/internal/home/clients.go b/internal/home/clients.go index 12f5b32d..8807fa89 100644 --- a/internal/home/clients.go +++ b/internal/home/clients.go @@ -29,25 +29,25 @@ var webHandlersRegistered = false // Client contains information about persistent clients. type Client struct { - IDs []string - Tags []string - Name string - UseOwnSettings bool // false: use global settings - FilteringEnabled bool - SafeSearchEnabled bool - SafeBrowsingEnabled bool - ParentalEnabled bool - - UseOwnBlockedServices bool // false: use global settings - BlockedServices []string - - Upstreams []string // list of upstream servers to be used for the client's requests - - // Custom upstream config for this client - // nil: not yet initialized - // not nil, but empty: initialized, no good upstreams - // not nil, not empty: Upstreams ready to be used + // upstreamConfig is the custom upstream config for this client. If + // it's nil, it has not been initialized yet. If it's non-nil and + // empty, there are no valid upstreams. If it's non-nil and non-empty, + // these upstream must be used. upstreamConfig *proxy.UpstreamConfig + + Name string + + IDs []string + Tags []string + BlockedServices []string + Upstreams []string + + UseOwnSettings bool + FilteringEnabled bool + SafeSearchEnabled bool + SafeBrowsingEnabled bool + ParentalEnabled bool + UseOwnBlockedServices bool } type clientSource uint @@ -63,9 +63,9 @@ const ( // RuntimeClient information type RuntimeClient struct { + WhoisInfo *RuntimeClientWhoisInfo Host string Source clientSource - WhoisInfo *RuntimeClientWhoisInfo } // RuntimeClientWhoisInfo is the filtered WHOIS data for a runtime client. diff --git a/internal/home/clientshttp.go b/internal/home/clientshttp.go index 21df856b..b283d623 100644 --- a/internal/home/clientshttp.go +++ b/internal/home/clientshttp.go @@ -7,31 +7,38 @@ import ( "net/http" ) +// clientJSON is a common structure used by several handlers to deal with +// clients. Some of the fields are only necessary in one or two handlers and +// are thus made pointers with an omitempty tag. +// +// TODO(a.garipov): Consider using nullbool and an optional string here? Or +// split into several structs? type clientJSON struct { - IDs []string `json:"ids"` - Tags []string `json:"tags"` - Name string `json:"name"` - UseGlobalSettings bool `json:"use_global_settings"` - FilteringEnabled bool `json:"filtering_enabled"` - ParentalEnabled bool `json:"parental_enabled"` - SafeSearchEnabled bool `json:"safesearch_enabled"` - SafeBrowsingEnabled bool `json:"safebrowsing_enabled"` + // Disallowed, if non-nil and false, means that the client's IP is + // allowed. Otherwise, the IP is blocked. + Disallowed *bool `json:"disallowed,omitempty"` - UseGlobalBlockedServices bool `json:"use_global_blocked_services"` - BlockedServices []string `json:"blocked_services"` + // DisallowedRule is the rule due to which the client is disallowed. + // If Disallowed is true and this string is empty, the client IP is + // disallowed by the "allowed IP list", that is it is not included in + // the allowlist. + DisallowedRule *string `json:"disallowed_rule,omitempty"` - Upstreams []string `json:"upstreams"` + WhoisInfo *RuntimeClientWhoisInfo `json:"whois_info,omitempty"` - WhoisInfo *RuntimeClientWhoisInfo `json:"whois_info"` + Name string `json:"name"` - // Disallowed - if true -- client's IP is not disallowed - // Otherwise, it is blocked. - Disallowed bool `json:"disallowed"` + BlockedServices []string `json:"blocked_services"` + IDs []string `json:"ids"` + Tags []string `json:"tags"` + Upstreams []string `json:"upstreams"` - // DisallowedRule - the rule due to which the client is disallowed - // If Disallowed is true, and this string is empty - it means that the client IP - // is disallowed by the "allowed IP list", i.e. it is not included in allowed. - DisallowedRule string `json:"disallowed_rule"` + FilteringEnabled bool `json:"filtering_enabled"` + ParentalEnabled bool `json:"parental_enabled"` + SafeBrowsingEnabled bool `json:"safebrowsing_enabled"` + SafeSearchEnabled bool `json:"safesearch_enabled"` + UseGlobalBlockedServices bool `json:"use_global_blocked_services"` + UseGlobalSettings bool `json:"use_global_settings"` } type runtimeClientJSON struct { @@ -126,8 +133,6 @@ func clientToJSON(c *Client) clientJSON { BlockedServices: c.BlockedServices, Upstreams: c.Upstreams, - - WhoisInfo: &RuntimeClientWhoisInfo{}, } return cj @@ -243,7 +248,8 @@ func (clients *clientsContainer) handleFindClient(w http.ResponseWriter, r *http } } else { cj = clientToJSON(c) - cj.Disallowed, cj.DisallowedRule = clients.dnsServer.IsBlockedIP(ip) + disallowed, rule := clients.dnsServer.IsBlockedIP(ip) + cj.Disallowed, cj.DisallowedRule = &disallowed, &rule } data = append(data, map[string]clientJSON{ @@ -279,8 +285,8 @@ func (clients *clientsContainer) findRuntime(ip net.IP, idStr string) (cj client cj = clientJSON{ IDs: []string{idStr}, - Disallowed: disallowed, - DisallowedRule: rule, + Disallowed: &disallowed, + DisallowedRule: &rule, WhoisInfo: &RuntimeClientWhoisInfo{}, } @@ -288,7 +294,8 @@ func (clients *clientsContainer) findRuntime(ip net.IP, idStr string) (cj client } cj = runtimeClientToJSON(idStr, rc) - cj.Disallowed, cj.DisallowedRule = clients.dnsServer.IsBlockedIP(ip) + disallowed, rule := clients.dnsServer.IsBlockedIP(ip) + cj.Disallowed, cj.DisallowedRule = &disallowed, &rule return cj, true } diff --git a/openapi/CHANGELOG.md b/openapi/CHANGELOG.md index 7ee40a5b..0fd19bb8 100644 --- a/openapi/CHANGELOG.md +++ b/openapi/CHANGELOG.md @@ -4,6 +4,15 @@ ## v0.106: API changes +### The field `"supported_tags"` in `GET /control/clients` + +* Prefiously undocumented field `"supported_tags"` in the response is now + documented. + +### The field `"whois_info"` in `GET /control/clients` + +* Objects in the `"auto_clients"` array now have the `"whois_info"` field. + ### New response code in `POST /control/login` * `429` is returned when user is out of login attempts. It adds the diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 3a0df747..187d764e 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -2234,6 +2234,10 @@ 'type': 'array' 'items': 'type': 'string' + 'tags': + 'items': + 'type': 'string' + 'type': 'array' 'ClientAuto': 'type': 'object' 'description': 'Auto-Client information' @@ -2250,6 +2254,8 @@ 'type': 'string' 'description': 'The source of this information' 'example': 'etc/hosts' + 'whois_info': + '$ref': '#/components/schemas/WhoisInfo' 'ClientUpdate': 'type': 'object' 'description': 'Client update request' @@ -2384,6 +2390,10 @@ '$ref': '#/components/schemas/ClientsArray' 'auto_clients': '$ref': '#/components/schemas/ClientsAutoArray' + 'supported_tags': + 'items': + 'type': 'string' + 'type': 'array' 'ClientsArray': 'type': 'array' 'items':