Pull request: 4535-list-services
Updates #4535. * commit '986124948a21b5dfebb0bd6a9f948911b0a4b938': all: imp client, add api chlog filtering: imp code Add '/blocked_services/services' API
This commit is contained in:
commit
35c1d84b42
|
@ -1355,6 +1355,19 @@ Internally, all supported services are stored as a map:
|
|||
service name -> list of rules
|
||||
|
||||
|
||||
### API: Get blocked services list of available services
|
||||
|
||||
Request:
|
||||
|
||||
GET /control/blocked_services/services
|
||||
|
||||
Response:
|
||||
|
||||
200 OK
|
||||
|
||||
[ "name1", ... ]
|
||||
|
||||
|
||||
### API: Get blocked services list
|
||||
|
||||
Request:
|
||||
|
|
|
@ -20,6 +20,11 @@ and this project adheres to
|
|||
- Weaker cipher suites that use the CBC (cipher block chaining) mode of
|
||||
operation have been disabled ([#2993]).
|
||||
|
||||
### Added
|
||||
|
||||
- A new HTTP API, `GET /control/blocked_services/services`, that lists all
|
||||
available blocked services ([#4535]).
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Ports 784 and 8853 for DNS-over-QUIC in Docker images. Users who still serve
|
||||
|
@ -34,6 +39,7 @@ and this project adheres to
|
|||
- Unnecessary logging of non-critical statistics errors ([#4850]).
|
||||
|
||||
[#2993]: https://github.com/AdguardTeam/AdGuardHome/issues/2993
|
||||
[#4535]: https://github.com/AdguardTeam/AdGuardHome/issues/4535
|
||||
[#4745]: https://github.com/AdguardTeam/AdGuardHome/issues/4745
|
||||
[#4850]: https://github.com/AdguardTeam/AdGuardHome/issues/4850
|
||||
|
||||
|
@ -59,7 +65,7 @@ See also the [v0.107.11 GitHub milestone][ms-v0.107.11].
|
|||
|
||||
### Changed
|
||||
|
||||
- DNS-over-QUIC connections now use keptalive.
|
||||
- DNS-over-QUIC connections now use keepalive.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -2,6 +2,21 @@ import { createAction } from 'redux-actions';
|
|||
import apiClient from '../api/Api';
|
||||
import { addErrorToast, addSuccessToast } from './toasts';
|
||||
|
||||
export const getBlockedServicesAvailableServicesRequest = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_REQUEST');
|
||||
export const getBlockedServicesAvailableServicesFailure = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_FAILURE');
|
||||
export const getBlockedServicesAvailableServicesSuccess = createAction('GET_BLOCKED_SERVICES_AVAILABLE_SERVICES_SUCCESS');
|
||||
|
||||
export const getBlockedServicesAvailableServices = () => async (dispatch) => {
|
||||
dispatch(getBlockedServicesAvailableServicesRequest());
|
||||
try {
|
||||
const data = await apiClient.getBlockedServicesAvailableServices();
|
||||
dispatch(getBlockedServicesAvailableServicesSuccess(data));
|
||||
} catch (error) {
|
||||
dispatch(addErrorToast({ error }));
|
||||
dispatch(getBlockedServicesAvailableServicesFailure());
|
||||
}
|
||||
};
|
||||
|
||||
export const getBlockedServicesRequest = createAction('GET_BLOCKED_SERVICES_REQUEST');
|
||||
export const getBlockedServicesFailure = createAction('GET_BLOCKED_SERVICES_FAILURE');
|
||||
export const getBlockedServicesSuccess = createAction('GET_BLOCKED_SERVICES_SUCCESS');
|
||||
|
|
|
@ -481,10 +481,17 @@ class Api {
|
|||
}
|
||||
|
||||
// Blocked services
|
||||
BLOCKED_SERVICES_SERVICES = { path: 'blocked_services/services', method: 'GET' };
|
||||
|
||||
BLOCKED_SERVICES_LIST = { path: 'blocked_services/list', method: 'GET' };
|
||||
|
||||
BLOCKED_SERVICES_SET = { path: 'blocked_services/set', method: 'POST' };
|
||||
|
||||
getBlockedServicesAvailableServices() {
|
||||
const { path, method } = this.BLOCKED_SERVICES_SERVICES;
|
||||
return this.makeRequest(path, method);
|
||||
}
|
||||
|
||||
getBlockedServices() {
|
||||
const { path, method } = this.BLOCKED_SERVICES_LIST;
|
||||
return this.makeRequest(path, method);
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
// This file was autogenerated. Please do not change.
|
||||
// All changes will be overwrited on commit.
|
||||
export default class BlockedServicesApi {
|
||||
static async blockedServicesAvailableServices(): Promise<string[] | Error> {
|
||||
return await fetch(`/control/blocked_services/services`, {
|
||||
method: 'GET',
|
||||
}).then(async (res) => {
|
||||
if (res.status === 200) {
|
||||
return res.json();
|
||||
} else {
|
||||
return new Error(String(res.status));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static async blockedServicesList(): Promise<string[] | Error> {
|
||||
return await fetch(`/control/blocked_services/list`, {
|
||||
method: 'GET',
|
||||
|
|
|
@ -7,19 +7,21 @@ import (
|
|||
"github.com/AdguardTeam/AdGuardHome/internal/aghhttp"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/AdguardTeam/urlfilter/rules"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var serviceRules map[string][]*rules.NetworkRule // service name -> filtering rules
|
||||
|
||||
// svc represents a single blocked service.
|
||||
type svc struct {
|
||||
name string
|
||||
rules []string
|
||||
}
|
||||
|
||||
// servicesData contains raw blocked service data.
|
||||
//
|
||||
// Keep in sync with:
|
||||
// client/src/helpers/constants.js
|
||||
// client/src/components/ui/Icons.js
|
||||
var serviceRulesArray = []svc{{
|
||||
// - client/src/helpers/constants.js
|
||||
// - client/src/components/ui/Icons.js
|
||||
var servicesData = []svc{{
|
||||
name: "whatsapp",
|
||||
rules: []string{
|
||||
"||wa.me^",
|
||||
|
@ -365,21 +367,38 @@ var serviceRulesArray = []svc{{
|
|||
},
|
||||
}}
|
||||
|
||||
// convert array to map
|
||||
// serviceRules maps a service ID to its filtering rules.
|
||||
var serviceRules map[string][]*rules.NetworkRule
|
||||
|
||||
// serviceIDs contains service IDs sorted alphabetically.
|
||||
var serviceIDs []string
|
||||
|
||||
// initBlockedServices initializes package-level blocked service data.
|
||||
func initBlockedServices() {
|
||||
serviceRules = make(map[string][]*rules.NetworkRule)
|
||||
for _, s := range serviceRulesArray {
|
||||
netRules := []*rules.NetworkRule{}
|
||||
l := len(servicesData)
|
||||
serviceIDs = make([]string, l)
|
||||
serviceRules = make(map[string][]*rules.NetworkRule, l)
|
||||
|
||||
for i, s := range servicesData {
|
||||
netRules := make([]*rules.NetworkRule, 0, len(s.rules))
|
||||
for _, text := range s.rules {
|
||||
rule, err := rules.NewNetworkRule(text, BlockedSvcsListID)
|
||||
if err != nil {
|
||||
log.Error("rules.NewNetworkRule: %s rule: %s", err, text)
|
||||
log.Error("parsing blocked service %q rule %q: %s", s.name, text, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
netRules = append(netRules, rule)
|
||||
}
|
||||
|
||||
serviceIDs[i] = s.name
|
||||
serviceRules[s.name] = netRules
|
||||
}
|
||||
|
||||
slices.Sort(serviceIDs)
|
||||
|
||||
log.Debug("filtering: initialized %d services", l)
|
||||
}
|
||||
|
||||
// BlockedSvcKnown - return TRUE if a blocked service name is known
|
||||
|
@ -411,6 +430,16 @@ func (d *DNSFilter) ApplyBlockedServices(setts *Settings, list []string, global
|
|||
}
|
||||
}
|
||||
|
||||
func (d *DNSFilter) handleBlockedServicesAvailableServices(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(serviceIDs)
|
||||
if err != nil {
|
||||
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding available services: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Request) {
|
||||
d.confLock.RLock()
|
||||
list := d.Config.BlockedServices
|
||||
|
@ -419,7 +448,7 @@ func (d *DNSFilter) handleBlockedServicesList(w http.ResponseWriter, r *http.Req
|
|||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(list)
|
||||
if err != nil {
|
||||
aghhttp.Error(r, w, http.StatusInternalServerError, "json.Encode: %s", err)
|
||||
aghhttp.Error(r, w, http.StatusInternalServerError, "encoding services: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -445,6 +474,7 @@ func (d *DNSFilter) handleBlockedServicesSet(w http.ResponseWriter, r *http.Requ
|
|||
|
||||
// registerBlockedServicesHandlers - register HTTP handlers
|
||||
func (d *DNSFilter) registerBlockedServicesHandlers() {
|
||||
d.Config.HTTPRegister(http.MethodGet, "/control/blocked_services/services", d.handleBlockedServicesAvailableServices)
|
||||
d.Config.HTTPRegister(http.MethodGet, "/control/blocked_services/list", d.handleBlockedServicesList)
|
||||
d.Config.HTTPRegister(http.MethodPost, "/control/blocked_services/set", d.handleBlockedServicesSet)
|
||||
}
|
||||
|
|
|
@ -296,9 +296,11 @@ func cloneRewrites(entries []*LegacyRewrite) (clone []*LegacyRewrite) {
|
|||
return clone
|
||||
}
|
||||
|
||||
// SetFilters - set new filters (synchronously or asynchronously)
|
||||
// When filters are set asynchronously, the old filters continue working until the new filters are ready.
|
||||
// In this case the caller must ensure that the old filter files are intact.
|
||||
// SetFilters sets new filters, synchronously or asynchronously. When filters
|
||||
// are set asynchronously, the old filters continue working until the new
|
||||
// filters are ready.
|
||||
//
|
||||
// In this case the caller must ensure that the old filter files are intact.
|
||||
func (d *DNSFilter) SetFilters(blockFilters, allowFilters []Filter, async bool) error {
|
||||
if async {
|
||||
params := filtersInitializerParams{
|
||||
|
|
|
@ -130,10 +130,9 @@ func matchDomainWildcard(host, wildcard string) (ok bool) {
|
|||
//
|
||||
// The sorting priority:
|
||||
//
|
||||
// A and AAAA > CNAME
|
||||
// wildcard > exact
|
||||
// lower level wildcard > higher level wildcard
|
||||
//
|
||||
// 1. A and AAAA > CNAME
|
||||
// 2. wildcard > exact
|
||||
// 3. lower level wildcard > higher level wildcard
|
||||
type rewritesSorted []*LegacyRewrite
|
||||
|
||||
// Len implements the sort.Interface interface for legacyRewritesSorted.
|
||||
|
|
|
@ -4,6 +4,15 @@
|
|||
|
||||
## v0.108.0: API changes
|
||||
|
||||
## v0.107.12: API changes
|
||||
|
||||
### `GET /control/blocked_services/services`
|
||||
|
||||
* The new `GET /control/blocked_services/services` HTTP API allows inspecting
|
||||
all available services.
|
||||
|
||||
## v0.107.7: API changes
|
||||
|
||||
### The new optional field `"ecs"` in `QueryLogItem`
|
||||
|
||||
* The new optional field `"ecs"` in `GET /control/querylog` contains the IP
|
||||
|
|
|
@ -874,6 +874,19 @@
|
|||
'summary': 'Set (dis)allowed clients, blocked hosts, etc.'
|
||||
'tags':
|
||||
- 'clients'
|
||||
'/blocked_services/services':
|
||||
'get':
|
||||
'tags':
|
||||
- 'blocked_services'
|
||||
'operationId': 'blockedServicesAvailableServices'
|
||||
'summary': 'Get available services to use for blocking'
|
||||
'responses':
|
||||
'200':
|
||||
'description': 'OK.'
|
||||
'content':
|
||||
'application/json':
|
||||
'schema':
|
||||
'$ref': '#/components/schemas/BlockedServicesArray'
|
||||
'/blocked_services/list':
|
||||
'get':
|
||||
'tags':
|
||||
|
|
Loading…
Reference in New Issue