Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
07d42c9
Add Attack Protection tab
tung2744 Dec 17, 2025
99c0411
Add attack protection route
tung2744 Dec 18, 2025
dca942b
Implement IP blocklist screen ui
tung2744 Dec 19, 2025
949e106
Define ip blocklist form state
tung2744 Dec 19, 2025
e2bfece
Add button to check ip address
tung2744 Dec 19, 2025
309ccaa
Only allow country codes with 2 characters
tung2744 Dec 19, 2025
45b809c
Setup checkIP mutation
tung2744 Dec 19, 2025
8d27d0b
Implement checkIP mutation
tung2744 Dec 19, 2025
e31ed26
Integrate check ip mutation in ui
tung2744 Dec 19, 2025
6496d9e
Provide IPBlocklistService
tung2744 Dec 19, 2025
8c89427
Display ip check result in ip blocklist form
tung2744 Dec 19, 2025
de5888a
Display a readable error for invalid ip address
tung2744 Dec 19, 2025
68ef377
Remove attack protection index page
tung2744 Dec 19, 2025
18434cf
Update .make-lint-expect
tung2744 Dec 19, 2025
f73ab51
Remove incorrect usage of background context
tung2744 Dec 19, 2025
99e4677
Update network protection config according to latest spec
tung2744 Dec 22, 2025
11406e4
Update ip blocklist middleware implementation according to new config
tung2744 Dec 22, 2025
f0108b8
Rename files
tung2744 Dec 22, 2025
3255d8d
Update deps of IPFilterMiddleware
tung2744 Dec 22, 2025
e10f1b0
Add network_protection to portal config
tung2744 Dec 22, 2025
76233a0
Update IPBlocklistScreen to set and read config correctly
tung2744 Dec 22, 2025
59a9020
Handle validation error of cidrs correctly
tung2744 Dec 22, 2025
79fef2a
Disable IP Blocklist Form if portal do not understand the config
tung2744 Dec 22, 2025
f97d46a
Fix app config form will show incorrect state for a while after save
tung2744 Dec 23, 2025
9e49816
Reset check ip state when config changes
tung2744 Dec 23, 2025
7abf277
Remove "Attack Protection" from screen title
tung2744 Dec 23, 2025
e2cbe25
Use newline to separate cidrs
tung2744 Dec 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .make-lint-expect
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pkg/portal/graphql/chart.go cannot import github.com/authgear/authgear-server/pk
pkg/portal/graphql/collaborator_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/domain_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/hook_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/ip_blocklist_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/nodes.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/sms_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
pkg/portal/graphql/smtp_mutation.go cannot import github.com/authgear/authgear-server/pkg/graphqlgo/relay
Expand Down
2 changes: 1 addition & 1 deletion pkg/auth/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func NewRouter(p *deps.RootProvider, configSource *configsource.ConfigSource) ht
projectRootChain := httproute.Chain(
baseChain,
MakeWebAppRequestMiddleware(p, configSource, newWebAppRequestMiddleware),
p.Middleware(newIPBlocklistMiddleware),
p.Middleware(newIPFilterMiddleware),
p.Middleware(newProjectRootDynamicCSPMiddleware),
)

Expand Down
6 changes: 3 additions & 3 deletions pkg/auth/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/auth/wire_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,9 @@ func newDPoPMiddleware(p *deps.RequestProvider) httproute.Middleware {
))
}

func newIPBlocklistMiddleware(p *deps.RequestProvider) httproute.Middleware {
func newIPFilterMiddleware(p *deps.RequestProvider) httproute.Middleware {
panic(wire.Build(
DependencySet,
wire.Bind(new(httproute.Middleware), new(*networkprotection.IPBlocklistMiddleware)),
wire.Bind(new(httproute.Middleware), new(*networkprotection.IPFilterMiddleware)),
))
}
74 changes: 66 additions & 8 deletions pkg/lib/config/network_protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ var _ = Schema.Add("NetworkProtectionConfig", `
"type": "object",
"additionalProperties": false,
"properties": {
"ip_blocklist": { "$ref": "#/$defs/NetworkIPBlocklistConfig" }
"ip_filter": { "$ref": "#/$defs/IPFilterConfig" }
}
}
`)

var _ = Schema.Add("NetworkIPBlocklistConfig", `
var _ = Schema.Add("IPFilterAction", `
{
"type": "string",
"enum": ["allow", "deny"]
}
`)

var _ = Schema.Add("IPFilterSource", `
{
"type": "object",
"additionalProperties": false,
Expand All @@ -19,19 +26,70 @@ var _ = Schema.Add("NetworkIPBlocklistConfig", `
"type": "array",
"items": { "type": "string", "format": "x_cidr" }
},
"country_codes": {
"geo_location_codes": {
"type": "array",
"items": { "type": "string" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep the restriction that only allows two-character country codes

}
}
}
`)

var _ = Schema.Add("IPFilterRule", `
{
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"action": { "$ref": "#/$defs/IPFilterAction" },
"source": { "$ref": "#/$defs/IPFilterSource" }
},
"required": ["action", "source"]
}
`)

var _ = Schema.Add("IPFilterConfig", `
{
"type": "object",
"additionalProperties": false,
"properties": {
"default_action": { "$ref": "#/$defs/IPFilterAction" },
"rules": {
"type": "array",
"items": { "type": "string", "minLength": 2, "maxLength": 2 }
"items": { "$ref": "#/$defs/IPFilterRule" }
}
}
}
`)

type NetworkProtectionConfig struct {
IPBlocklist *NetworkIPBlocklistConfig `json:"ip_blocklist,omitempty"`
IPFilter *IPFilterConfig `json:"ip_filter,omitempty"`
}

type IPFilterConfig struct {
DefaultAction IPFilterAction `json:"default_action,omitempty"`
Rules []*IPFilterRule `json:"rules,omitempty"`
}

func (c *IPFilterConfig) SetDefaults() {
if c.DefaultAction == "" {
c.DefaultAction = IPFilterActionAllow
}
}

type IPFilterAction string

const (
IPFilterActionAllow IPFilterAction = "allow"
IPFilterActionDeny IPFilterAction = "deny"
)

type IPFilterRule struct {
Name string `json:"name"`
Action IPFilterAction `json:"action"`
Source IPFilterSource `json:"source"`
}

type NetworkIPBlocklistConfig struct {
CIDRs []string `json:"cidrs,omitempty"`
CountryCodes []string `json:"country_codes,omitempty"`
type IPFilterSource struct {
CIDRs []string `json:"cidrs,omitempty"`
GeoLocationCodes []string `json:"geo_location_codes,omitempty"`
}
70 changes: 57 additions & 13 deletions pkg/lib/config/testdata/config_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1542,32 +1542,76 @@ config:
logo_uri: http://example.com/logo.png

---
name: protection-config
name: network-protection-config-valid
error: null
config:
id: test
http:
public_origin: http://test
network_protection:
ip_blocklist:
cidrs:
- 2.2.2.2/32
- 2001:db8::/32
country_codes:
- HK
- GB
ip_filter:
default_action: deny
rules:
- name: allow-office-us
action: allow
source:
cidrs: ["192.168.1.0/24", "2001:db8::/32"]
geo_location_codes: ["US"]
- name: block-countries
action: deny
source:
geo_location_codes: ["KP", "IR"]

---
name: protection-config-invalid-cidr
name: network-protection-config-invalid-cidr
error: |-
invalid configuration:
/network_protection/ip_blocklist/cidrs/0: format
/network_protection/ip_filter/rules/0/source/cidrs/0: format
map[error:invalid CIDR: invalid CIDR address: 192.168.1.1 format:x_cidr]
config:
id: test
http:
public_origin: http://test
network_protection:
ip_blocklist:
cidrs:
- 192.168.1.1
ip_filter:
default_action: allow
rules:
- name: invalid-cidr-rule
action: deny
source:
cidrs:
- 192.168.1.1
---
name: network-protection-config-invalid-action
error: |-
invalid configuration:
/network_protection/ip_filter/rules/0/action: enum
map[actual:invalid expected:[allow deny]]
config:
id: test
http:
public_origin: http://test
network_protection:
ip_filter:
default_action: allow
rules:
- name: invalid-action-rule
action: invalid
source:
cidrs: ["1.2.3.4/32"]
---
name: network-protection-config-missing-rule-fields
error: |-
invalid configuration:
/network_protection/ip_filter/rules/0: required
map[actual:[name] expected:[action source] missing:[action source]]
config:
id: test
http:
public_origin: http://test
network_protection:
ip_filter:
default_action: allow
rules:
- name: missing-fields

3 changes: 2 additions & 1 deletion pkg/lib/config/testdata/default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,8 @@ account_migration:
captcha: {}
bot_protection: {}
network_protection:
ip_blocklist: {}
ip_filter:
default_action: allow
test_mode:
oob_otp:
enabled: false
Expand Down
2 changes: 1 addition & 1 deletion pkg/lib/networkprotection/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import (
)

var DependencySet = wire.NewSet(
wire.Struct(new(IPBlocklistMiddleware), "*"),
wire.Struct(new(IPFilterMiddleware), "*"),
)
64 changes: 0 additions & 64 deletions pkg/lib/networkprotection/ip_blocklist_middleware.go

This file was deleted.

Loading