mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-21 23:53:14 +01:00
Update GitHub Actions and Enhance golangci-lint (#1075)
This PR showcases the implementation of additional linter rules. I've updated the golangci-lint GitHub Actions to the latest available version. This update makes sure that the tool works the same way locally - assuming being updated regularly - and with the GitHub Actions. I've also taken care of keeping all the GitHub Actions up to date, which helps our code stay current. But there's one part, goreleaser that's a bit tricky to test on our computers. So, it's important to take a close look at that. To make it easier to understand what I've done, I've made separate changes for each thing that the new linters found. This should help the people reviewing the changes see what's going on more clearly. Some of the changes might not be obvious at first glance. Things to consider for the future CI runs on Ubuntu so the static analysis only happens for Linux. Consider running it for the rest: Darwin, Windows
This commit is contained in:
parent
8524cc75d6
commit
bb40325977
6
.github/workflows/golang-test-darwin.yml
vendored
6
.github/workflows/golang-test-darwin.yml
vendored
@ -15,14 +15,14 @@ jobs:
|
|||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20.x"
|
go-version: "1.20.x"
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: macos-go-${{ hashFiles('**/go.sum') }}
|
key: macos-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
12
.github/workflows/golang-test-linux.yml
vendored
12
.github/workflows/golang-test-linux.yml
vendored
@ -18,13 +18,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20.x"
|
go-version: "1.20.x"
|
||||||
|
|
||||||
|
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@ -32,7 +32,7 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-multilib
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev gcc-multilib
|
||||||
@ -47,13 +47,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20.x"
|
go-version: "1.20.x"
|
||||||
|
|
||||||
|
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@ -61,7 +61,7 @@ jobs:
|
|||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
||||||
|
9
.github/workflows/golangci-lint.yml
vendored
9
.github/workflows/golangci-lint.yml
vendored
@ -8,14 +8,13 @@ jobs:
|
|||||||
name: lint
|
name: lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20.x"
|
go-version: "1.20.x"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v2
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
|
||||||
args: --timeout=6m
|
|
48
.github/workflows/release.yml
vendored
48
.github/workflows/release.yml
vendored
@ -29,20 +29,24 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
flags: ""
|
||||||
steps:
|
steps:
|
||||||
|
- if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
|
run: echo "flags=--snapshot" >> $GITHUB_ENV
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # It is required for GoReleaser to work properly
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
||||||
-
|
-
|
||||||
name: Set up Go
|
name: Set up Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20"
|
go-version: "1.20"
|
||||||
-
|
-
|
||||||
name: Cache Go modules
|
name: Cache Go modules
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
@ -56,10 +60,10 @@ jobs:
|
|||||||
run: git --no-pager diff --exit-code
|
run: git --no-pager diff --exit-code
|
||||||
-
|
-
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v2
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v2
|
||||||
-
|
-
|
||||||
name: Login to Docker hub
|
name: Login to Docker hub
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
@ -82,10 +86,10 @@ jobs:
|
|||||||
run: rsrc -arch 386 -ico client/ui/netbird.ico -manifest client/manifest.xml -o client/resources_windows_386.syso
|
run: rsrc -arch 386 -ico client/ui/netbird.ico -manifest client/manifest.xml -o client/resources_windows_386.syso
|
||||||
-
|
-
|
||||||
name: Run GoReleaser
|
name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v2
|
uses: goreleaser/goreleaser-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.GORELEASER_VER }}
|
version: ${{ env.GORELEASER_VER }}
|
||||||
args: release --rm-dist
|
args: release --rm-dist ${{ env.flags }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
||||||
@ -93,7 +97,7 @@ jobs:
|
|||||||
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||||
-
|
-
|
||||||
name: upload non tags for debug purposes
|
name: upload non tags for debug purposes
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: release
|
name: release
|
||||||
path: dist/
|
path: dist/
|
||||||
@ -102,17 +106,19 @@ jobs:
|
|||||||
release_ui:
|
release_ui:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
|
run: echo "flags=--snapshot" >> $GITHUB_ENV
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # It is required for GoReleaser to work properly
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20"
|
go-version: "1.20"
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-ui-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-ui-go-${{ hashFiles('**/go.sum') }}
|
||||||
@ -132,17 +138,17 @@ jobs:
|
|||||||
- name: Generate windows rsrc
|
- name: Generate windows rsrc
|
||||||
run: rsrc -arch amd64 -ico client/ui/netbird.ico -manifest client/ui/manifest.xml -o client/ui/resources_windows_amd64.syso
|
run: rsrc -arch amd64 -ico client/ui/netbird.ico -manifest client/ui/manifest.xml -o client/ui/resources_windows_amd64.syso
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v2
|
uses: goreleaser/goreleaser-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.GORELEASER_VER }}
|
version: ${{ env.GORELEASER_VER }}
|
||||||
args: release --config .goreleaser_ui.yaml --rm-dist
|
args: release --config .goreleaser_ui.yaml --rm-dist ${{ env.flags }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
||||||
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||||
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||||
- name: upload non tags for debug purposes
|
- name: upload non tags for debug purposes
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: release-ui
|
name: release-ui
|
||||||
path: dist/
|
path: dist/
|
||||||
@ -151,19 +157,21 @@ jobs:
|
|||||||
release_ui_darwin:
|
release_ui_darwin:
|
||||||
runs-on: macos-11
|
runs-on: macos-11
|
||||||
steps:
|
steps:
|
||||||
|
- if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
|
run: echo "flags=--snapshot" >> $GITHUB_ENV
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # It is required for GoReleaser to work properly
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
||||||
-
|
-
|
||||||
name: Set up Go
|
name: Set up Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20"
|
go-version: "1.20"
|
||||||
-
|
-
|
||||||
name: Cache Go modules
|
name: Cache Go modules
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-ui-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-ui-go-${{ hashFiles('**/go.sum') }}
|
||||||
@ -175,15 +183,15 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Run GoReleaser
|
name: Run GoReleaser
|
||||||
id: goreleaser
|
id: goreleaser
|
||||||
uses: goreleaser/goreleaser-action@v2
|
uses: goreleaser/goreleaser-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.GORELEASER_VER }}
|
version: ${{ env.GORELEASER_VER }}
|
||||||
args: release --config .goreleaser_ui_darwin.yaml --rm-dist
|
args: release --config .goreleaser_ui_darwin.yaml --rm-dist ${{ env.flags }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
-
|
-
|
||||||
name: upload non tags for debug purposes
|
name: upload non tags for debug purposes
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: release-ui-darwin
|
name: release-ui-darwin
|
||||||
path: dist/
|
path: dist/
|
||||||
|
@ -24,12 +24,12 @@ jobs:
|
|||||||
run: sudo apt-get install -y curl
|
run: sudo apt-get install -y curl
|
||||||
|
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.20.x"
|
go-version: "1.20.x"
|
||||||
|
|
||||||
- name: Cache Go modules
|
- name: Cache Go modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/go/pkg/mod
|
path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
54
.golangci.yaml
Normal file
54
.golangci.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
run:
|
||||||
|
# Timeout for analysis, e.g. 30s, 5m.
|
||||||
|
# Default: 1m
|
||||||
|
timeout: 6m
|
||||||
|
|
||||||
|
# This file contains only configs which differ from defaults.
|
||||||
|
# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
|
||||||
|
linters-settings:
|
||||||
|
errcheck:
|
||||||
|
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
|
||||||
|
# Such cases aren't reported by default.
|
||||||
|
# Default: false
|
||||||
|
check-type-assertions: false
|
||||||
|
|
||||||
|
govet:
|
||||||
|
# Enable all analyzers.
|
||||||
|
# Default: false
|
||||||
|
enable-all: false
|
||||||
|
enable:
|
||||||
|
- nilness
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
## enabled by default
|
||||||
|
- errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
|
||||||
|
- gosimple # specializes in simplifying a code
|
||||||
|
- govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
|
||||||
|
- ineffassign # detects when assignments to existing variables are not used
|
||||||
|
- staticcheck # is a go vet on steroids, applying a ton of static analysis checks
|
||||||
|
- typecheck # like the front-end of a Go compiler, parses and type-checks Go code
|
||||||
|
- unused # checks for unused constants, variables, functions and types
|
||||||
|
## disable by default but the have interesting results so lets add them
|
||||||
|
- bodyclose # checks whether HTTP response body is closed successfully
|
||||||
|
- nilerr # finds the code that returns nil even if it checks that the error is not nil
|
||||||
|
- nilnil # checks that there is no simultaneous return of nil error and an invalid value
|
||||||
|
- sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
|
||||||
|
- wastedassign # wastedassign finds wasted assignment statements
|
||||||
|
issues:
|
||||||
|
# Maximum count of issues with the same text.
|
||||||
|
# Set to 0 to disable.
|
||||||
|
# Default: 3
|
||||||
|
max-same-issues: 5
|
||||||
|
|
||||||
|
exclude-rules:
|
||||||
|
- path: sharedsock/filter.go
|
||||||
|
linters:
|
||||||
|
- unused
|
||||||
|
- path: client/firewall/iptables/rule.go
|
||||||
|
linters:
|
||||||
|
- unused
|
||||||
|
- path: mock.go
|
||||||
|
linters:
|
||||||
|
- nilnil
|
@ -18,10 +18,9 @@ func Encode(num uint32) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var encoded strings.Builder
|
var encoded strings.Builder
|
||||||
remainder := uint32(0)
|
|
||||||
|
|
||||||
for num > 0 {
|
for num > 0 {
|
||||||
remainder = num % base
|
remainder := num % base
|
||||||
encoded.WriteByte(alphabet[remainder])
|
encoded.WriteByte(alphabet[remainder])
|
||||||
num /= base
|
num /= base
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,9 @@ func statusFunc(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
ctx := internal.CtxInitState(context.Background())
|
ctx := internal.CtxInitState(context.Background())
|
||||||
|
|
||||||
resp, _ := getStatus(ctx, cmd)
|
resp, err := getStatus(ctx, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.GetStatus() == string(internal.StatusNeedsLogin) || resp.GetStatus() == string(internal.StatusLoginFailed) {
|
if resp.GetStatus() == string(internal.StatusNeedsLogin) || resp.GetStatus() == string(internal.StatusLoginFailed) {
|
||||||
@ -133,7 +133,7 @@ func statusFunc(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
outputInformationHolder := convertToStatusOutputOverview(resp)
|
outputInformationHolder := convertToStatusOutputOverview(resp)
|
||||||
|
|
||||||
statusOutputString := ""
|
var statusOutputString string
|
||||||
switch {
|
switch {
|
||||||
case detailFlag:
|
case detailFlag:
|
||||||
statusOutputString = parseToFullDetailSummary(outputInformationHolder)
|
statusOutputString = parseToFullDetailSummary(outputInformationHolder)
|
||||||
|
@ -146,12 +146,11 @@ func (d *DefaultManager) ApplyFiltering(networkMap *mgmProto.NetworkMap) {
|
|||||||
// if this rule is member of rule selection with more than DefaultIPsCountForSet
|
// if this rule is member of rule selection with more than DefaultIPsCountForSet
|
||||||
// it's IP address can be used in the ipset for firewall manager which supports it
|
// it's IP address can be used in the ipset for firewall manager which supports it
|
||||||
ipset := ipsetByRuleSelectors[d.getRuleGroupingSelector(r)]
|
ipset := ipsetByRuleSelectors[d.getRuleGroupingSelector(r)]
|
||||||
ipsetName := ""
|
|
||||||
if ipset.name == "" {
|
if ipset.name == "" {
|
||||||
d.ipsetCounter++
|
d.ipsetCounter++
|
||||||
ipset.name = fmt.Sprintf("nb%07d", d.ipsetCounter)
|
ipset.name = fmt.Sprintf("nb%07d", d.ipsetCounter)
|
||||||
}
|
}
|
||||||
ipsetName = ipset.name
|
ipsetName := ipset.name
|
||||||
pairID, rulePair, err := d.protoRuleToFirewallRule(r, ipsetName)
|
pairID, rulePair, err := d.protoRuleToFirewallRule(r, ipsetName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to apply firewall rule: %+v, %v", r, err)
|
log.Errorf("failed to apply firewall rule: %+v, %v", r, err)
|
||||||
|
@ -23,9 +23,6 @@ func TestGetConfig(t *testing.T) {
|
|||||||
assert.Equal(t, config.ManagementURL.String(), DefaultManagementURL)
|
assert.Equal(t, config.ManagementURL.String(), DefaultManagementURL)
|
||||||
assert.Equal(t, config.AdminURL.String(), DefaultAdminURL)
|
assert.Equal(t, config.AdminURL.String(), DefaultAdminURL)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
managementURL := "https://test.management.url:33071"
|
managementURL := "https://test.management.url:33071"
|
||||||
adminURL := "https://app.admin.url:443"
|
adminURL := "https://app.admin.url:443"
|
||||||
path := filepath.Join(t.TempDir(), "config.json")
|
path := filepath.Join(t.TempDir(), "config.json")
|
||||||
|
@ -777,7 +777,7 @@ func createWgInterfaceWithBind(t *testing.T) (*iface.WGIface, error) {
|
|||||||
newNet, err := stdnet.NewNet(nil)
|
newNet, err := stdnet.NewNet(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("create stdnet: %v", err)
|
t.Fatalf("create stdnet: %v", err)
|
||||||
return nil, nil
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
wgIface, err := iface.NewWGIFace("utun2301", "100.66.100.2/24", iface.DefaultMTU, nil, newNet)
|
wgIface, err := iface.NewWGIFace("utun2301", "100.66.100.2/24", iface.DefaultMTU, nil, newNet)
|
||||||
|
@ -992,14 +992,12 @@ func (e *Engine) parseNATExternalIPMappings() []string {
|
|||||||
log.Warnf("invalid external IP, %s, ignoring external IP mapping '%s'", external, mapping)
|
log.Warnf("invalid external IP, %s, ignoring external IP mapping '%s'", external, mapping)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if externalIP != nil {
|
mappedIP := externalIP.String()
|
||||||
mappedIP := externalIP.String()
|
if internalIP != nil {
|
||||||
if internalIP != nil {
|
mappedIP = mappedIP + "/" + internalIP.String()
|
||||||
mappedIP = mappedIP + "/" + internalIP.String()
|
|
||||||
}
|
|
||||||
mappedIPs = append(mappedIPs, mappedIP)
|
|
||||||
log.Infof("parsed external IP mapping of '%s' as '%s'", mapping, mappedIP)
|
|
||||||
}
|
}
|
||||||
|
mappedIPs = append(mappedIPs, mappedIP)
|
||||||
|
log.Infof("parsed external IP mapping of '%s' as '%s'", mapping, mappedIP)
|
||||||
}
|
}
|
||||||
if len(mappedIPs) != len(e.config.NATExternalIPs) {
|
if len(mappedIPs) != len(e.config.NATExternalIPs) {
|
||||||
log.Warnf("one or more external IP mappings failed to parse, ignoring all mappings")
|
log.Warnf("one or more external IP mappings failed to parse, ignoring all mappings")
|
||||||
|
@ -1046,7 +1046,7 @@ func startManagement(dataDir string) (*grpc.Server, string, error) {
|
|||||||
peersUpdateManager := server.NewPeersUpdateManager()
|
peersUpdateManager := server.NewPeersUpdateManager()
|
||||||
eventStore := &activity.InMemoryEventStore{}
|
eventStore := &activity.InMemoryEventStore{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", nil
|
return nil, "", err
|
||||||
}
|
}
|
||||||
accountManager, err := server.BuildManager(store, peersUpdateManager, nil, "", "",
|
accountManager, err := server.BuildManager(store, peersUpdateManager, nil, "", "",
|
||||||
eventStore)
|
eventStore)
|
||||||
|
@ -155,7 +155,10 @@ func (c *clientNetwork) startPeersStatusChangeWatcher() {
|
|||||||
|
|
||||||
func (c *clientNetwork) removeRouteFromWireguardPeer(peerKey string) error {
|
func (c *clientNetwork) removeRouteFromWireguardPeer(peerKey string) error {
|
||||||
state, err := c.statusRecorder.GetPeer(peerKey)
|
state, err := c.statusRecorder.GetPeer(peerKey)
|
||||||
if err != nil || state.ConnStatus != peer.StatusConnected {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if state.ConnStatus != peer.StatusConnected {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,11 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/netbirdio/netbird/client/internal/auth"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/client/internal/auth"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
@ -315,7 +316,7 @@ func (s *Server) WaitSSOLogin(callerCtx context.Context, msg *proto.WaitSSOLogin
|
|||||||
tokenInfo, err := s.oauthAuthFlow.flow.WaitToken(waitCTX, flowInfo)
|
tokenInfo, err := s.oauthAuthFlow.flow.WaitToken(waitCTX, flowInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == context.Canceled {
|
if err == context.Canceled {
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
s.oauthAuthFlow.expiresAt = time.Now()
|
s.oauthAuthFlow.expiresAt = time.Now()
|
||||||
|
@ -161,7 +161,7 @@ func getModulePath(name string) (string, error) {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// skip broken files
|
// skip broken files
|
||||||
return nil
|
return nil //nolint:nilerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.Type().IsRegular() {
|
if !info.Type().IsRegular() {
|
||||||
|
@ -146,9 +146,6 @@ func (c *wGConfigurer) removeAllowedIP(peerKey string, allowedIP string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
peer := wgtypes.PeerConfig{
|
peer := wgtypes.PeerConfig{
|
||||||
PublicKey: peerKeyParsed,
|
PublicKey: peerKeyParsed,
|
||||||
UpdateOnly: true,
|
UpdateOnly: true,
|
||||||
|
@ -1022,7 +1022,7 @@ func (am *DefaultAccountManager) lookupUserInCacheByEmail(email string, accountI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookupUserInCache looks up user in the IdP cache and returns it. If the user wasn't found, the function returns nil
|
// lookupUserInCache looks up user in the IdP cache and returns it. If the user wasn't found, the function returns nil
|
||||||
@ -1045,7 +1045,7 @@ func (am *DefaultAccountManager) lookupUserInCache(userID string, account *Accou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *DefaultAccountManager) refreshCache(accountID string) ([]*idp.UserData, error) {
|
func (am *DefaultAccountManager) refreshCache(accountID string) ([]*idp.UserData, error) {
|
||||||
|
@ -784,10 +784,6 @@ func TestAccountManager_AddPeer(t *testing.T) {
|
|||||||
serial := account.Network.CurrentSerial() // should be 0
|
serial := account.Network.CurrentSerial() // should be 0
|
||||||
|
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
@ -931,10 +927,6 @@ func TestAccountManager_NetworkUpdates(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
@ -1115,10 +1107,6 @@ func TestAccountManager_DeletePeer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userID, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
|
@ -3,13 +3,14 @@ package sqlite
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/netbirdio/netbird/management/server/activity"
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
|
|
||||||
// sqlite driver
|
// sqlite driver
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -24,15 +25,20 @@ const (
|
|||||||
"meta TEXT," +
|
"meta TEXT," +
|
||||||
" target_id TEXT);"
|
" target_id TEXT);"
|
||||||
|
|
||||||
selectStatement = "SELECT id, activity, timestamp, initiator_id, target_id, account_id, meta" +
|
selectDescQuery = "SELECT id, activity, timestamp, initiator_id, target_id, account_id, meta" +
|
||||||
" FROM events WHERE account_id = ? ORDER BY timestamp %s LIMIT ? OFFSET ?;"
|
" FROM events WHERE account_id = ? ORDER BY timestamp DESC LIMIT ? OFFSET ?;"
|
||||||
insertStatement = "INSERT INTO events(activity, timestamp, initiator_id, target_id, account_id, meta) " +
|
selectAscQuery = "SELECT id, activity, timestamp, initiator_id, target_id, account_id, meta" +
|
||||||
|
" FROM events WHERE account_id = ? ORDER BY timestamp ASC LIMIT ? OFFSET ?;"
|
||||||
|
insertQuery = "INSERT INTO events(activity, timestamp, initiator_id, target_id, account_id, meta) " +
|
||||||
"VALUES(?, ?, ?, ?, ?, ?)"
|
"VALUES(?, ?, ?, ?, ?, ?)"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Store is the implementation of the activity.Store interface backed by SQLite
|
// Store is the implementation of the activity.Store interface backed by SQLite
|
||||||
type Store struct {
|
type Store struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
insertStatement *sql.Stmt
|
||||||
|
selectAscStatement *sql.Stmt
|
||||||
|
selectDescStatement *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSQLiteStore creates a new Store with an event table if not exists.
|
// NewSQLiteStore creates a new Store with an event table if not exists.
|
||||||
@ -48,7 +54,27 @@ func NewSQLiteStore(dataDir string) (*Store, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Store{db: db}, nil
|
insertStmt, err := db.Prepare(insertQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDescStmt, err := db.Prepare(selectDescQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAscStmt, err := db.Prepare(selectAscQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Store{
|
||||||
|
db: db,
|
||||||
|
insertStatement: insertStmt,
|
||||||
|
selectDescStatement: selectDescStmt,
|
||||||
|
selectAscStatement: selectAscStmt,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func processResult(result *sql.Rows) ([]*activity.Event, error) {
|
func processResult(result *sql.Rows) ([]*activity.Event, error) {
|
||||||
@ -90,13 +116,9 @@ func processResult(result *sql.Rows) ([]*activity.Event, error) {
|
|||||||
|
|
||||||
// Get returns "limit" number of events from index ordered descending or ascending by a timestamp
|
// Get returns "limit" number of events from index ordered descending or ascending by a timestamp
|
||||||
func (store *Store) Get(accountID string, offset, limit int, descending bool) ([]*activity.Event, error) {
|
func (store *Store) Get(accountID string, offset, limit int, descending bool) ([]*activity.Event, error) {
|
||||||
order := "DESC"
|
stmt := store.selectDescStatement
|
||||||
if !descending {
|
if !descending {
|
||||||
order = "ASC"
|
stmt = store.selectAscStatement
|
||||||
}
|
|
||||||
stmt, err := store.db.Prepare(fmt.Sprintf(selectStatement, order))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := stmt.Query(accountID, limit, offset)
|
result, err := stmt.Query(accountID, limit, offset)
|
||||||
@ -110,12 +132,6 @@ func (store *Store) Get(accountID string, offset, limit int, descending bool) ([
|
|||||||
|
|
||||||
// Save an event in the SQLite events table
|
// Save an event in the SQLite events table
|
||||||
func (store *Store) Save(event *activity.Event) (*activity.Event, error) {
|
func (store *Store) Save(event *activity.Event) (*activity.Event, error) {
|
||||||
|
|
||||||
stmt, err := store.db.Prepare(insertStatement)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var jsonMeta string
|
var jsonMeta string
|
||||||
if event.Meta != nil {
|
if event.Meta != nil {
|
||||||
metaBytes, err := json.Marshal(event.Meta)
|
metaBytes, err := json.Marshal(event.Meta)
|
||||||
@ -125,7 +141,7 @@ func (store *Store) Save(event *activity.Event) (*activity.Event, error) {
|
|||||||
jsonMeta = string(metaBytes)
|
jsonMeta = string(metaBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := stmt.Exec(event.Activity, event.Timestamp, event.InitiatorID, event.TargetID, event.AccountID, jsonMeta)
|
result, err := store.insertStatement.Exec(event.Activity, event.Timestamp, event.InitiatorID, event.TargetID, event.AccountID, jsonMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ type MocAccountManager struct {
|
|||||||
|
|
||||||
func (a MocAccountManager) DeletePeer(accountID, peerID, userID string) (*Peer, error) {
|
func (a MocAccountManager) DeletePeer(accountID, peerID, userID string) (*Peer, error) {
|
||||||
delete(a.store.account.Peers, peerID)
|
delete(a.store.account.Peers, peerID)
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewManager(t *testing.T) {
|
func TestNewManager(t *testing.T) {
|
||||||
|
@ -231,10 +231,8 @@ func (h *GroupsHandler) GetGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
util.WriteJSONObject(w, toGroupResponse(account, group))
|
util.WriteJSONObject(w, toGroupResponse(account, group))
|
||||||
default:
|
default:
|
||||||
if err != nil {
|
util.WriteError(status.Errorf(status.NotFound, "HTTP method not found"), w)
|
||||||
util.WriteError(status.Errorf(status.NotFound, "HTTP method not found"), w)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +115,10 @@ func TestAuthMiddleware_Handler(t *testing.T) {
|
|||||||
|
|
||||||
handlerToTest.ServeHTTP(rec, req)
|
handlerToTest.ServeHTTP(rec, req)
|
||||||
|
|
||||||
if rec.Result().StatusCode != tc.expectedStatusCode {
|
result := rec.Result()
|
||||||
t.Errorf("expected status code %d, got %d", tc.expectedStatusCode, rec.Result().StatusCode)
|
defer result.Body.Close()
|
||||||
|
if result.StatusCode != tc.expectedStatusCode {
|
||||||
|
t.Errorf("expected status code %d, got %d", tc.expectedStatusCode, result.StatusCode)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ func TestAuth0_RequestJWTToken(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
body, err := io.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
assert.NoError(t, err, "unable to read the response body")
|
assert.NoError(t, err, "unable to read the response body")
|
||||||
|
|
||||||
|
@ -3,10 +3,6 @@ package idp
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/golang-jwt/jwt"
|
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"goauthentik.io/api/v3"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -14,6 +10,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"goauthentik.io/api/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AuthentikManager authentik manager client instance.
|
// AuthentikManager authentik manager client instance.
|
||||||
@ -236,6 +237,7 @@ func (am *AuthentikManager) UpdateUserAppMetadata(userID string, appMetadata App
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountUpdateUserAppMetadata()
|
am.appMetrics.IDPMetrics().CountUpdateUserAppMetadata()
|
||||||
@ -267,6 +269,7 @@ func (am *AuthentikManager) GetUserDataByID(userID string, appMetadata AppMetada
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountGetUserDataByID()
|
am.appMetrics.IDPMetrics().CountGetUserDataByID()
|
||||||
@ -294,6 +297,7 @@ func (am *AuthentikManager) GetAccount(accountID string) ([]*UserData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountGetAccount()
|
am.appMetrics.IDPMetrics().CountGetAccount()
|
||||||
@ -330,6 +334,7 @@ func (am *AuthentikManager) GetAllAccounts() (map[string][]*UserData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountGetAllAccounts()
|
am.appMetrics.IDPMetrics().CountGetAllAccounts()
|
||||||
@ -389,6 +394,7 @@ func (am *AuthentikManager) CreateUser(email, name, accountID, invitedByEmail st
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountCreateUser()
|
am.appMetrics.IDPMetrics().CountCreateUser()
|
||||||
@ -416,6 +422,7 @@ func (am *AuthentikManager) GetUserByEmail(email string) ([]*UserData, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if am.appMetrics != nil {
|
if am.appMetrics != nil {
|
||||||
am.appMetrics.IDPMetrics().CountGetUserByEmail()
|
am.appMetrics.IDPMetrics().CountGetUserByEmail()
|
||||||
@ -469,10 +476,11 @@ func (am *AuthentikManager) getUserGroupByName(name string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
groupList, _, err := am.apiClient.CoreApi.CoreGroupsList(ctx).Name(name).Execute()
|
groupList, resp, err := am.apiClient.CoreApi.CoreGroupsList(ctx).Name(name).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if groupList != nil {
|
if groupList != nil {
|
||||||
if len(groupList.Results) > 0 {
|
if len(groupList.Results) > 0 {
|
||||||
@ -485,6 +493,7 @@ func (am *AuthentikManager) getUserGroupByName(name string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusCreated {
|
if resp.StatusCode != http.StatusCreated {
|
||||||
return "", fmt.Errorf("unable to create user group, statusCode: %d", resp.StatusCode)
|
return "", fmt.Errorf("unable to create user group, statusCode: %d", resp.StatusCode)
|
||||||
|
@ -2,13 +2,14 @@ package idp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewAuthentikManager(t *testing.T) {
|
func TestNewAuthentikManager(t *testing.T) {
|
||||||
@ -133,6 +134,7 @@ func TestAuthentikRequestJWTToken(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
assert.NoError(t, err, "unable to read the response body")
|
assert.NoError(t, err, "unable to read the response body")
|
||||||
|
|
||||||
|
@ -4,15 +4,16 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
admin "google.golang.org/api/admin/directory/v1"
|
admin "google.golang.org/api/admin/directory/v1"
|
||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GoogleWorkspaceManager Google Workspace manager client instance.
|
// GoogleWorkspaceManager Google Workspace manager client instance.
|
||||||
@ -271,7 +272,8 @@ func getGoogleCredentials(serviceAccountKey string) (*google.Credentials, error)
|
|||||||
admin.AdminDirectoryUserScope,
|
admin.AdminDirectoryUserScope,
|
||||||
)
|
)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return creds, err
|
// No need to fallback to the default Google credentials path
|
||||||
|
return creds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("failed to retrieve Google credentials from ServiceAccountKey: %v", err)
|
log.Debugf("failed to retrieve Google credentials from ServiceAccountKey: %v", err)
|
||||||
|
@ -92,7 +92,7 @@ func NewManager(config Config, appMetrics telemetry.AppMetrics) (Manager, error)
|
|||||||
|
|
||||||
switch strings.ToLower(config.ManagerType) {
|
switch strings.ToLower(config.ManagerType) {
|
||||||
case "none", "":
|
case "none", "":
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
case "auth0":
|
case "auth0":
|
||||||
auth0ClientConfig := config.Auth0ClientCredentials
|
auth0ClientConfig := config.Auth0ClientCredentials
|
||||||
if config.ClientConfig != nil {
|
if config.ClientConfig != nil {
|
||||||
|
@ -145,6 +145,7 @@ func TestKeycloakRequestJWTToken(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
assert.NoError(t, err, "unable to read the response body")
|
assert.NoError(t, err, "unable to read the response body")
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ func TestZitadelRequestJWTToken(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
assert.NoError(t, err, "unable to read the response body")
|
assert.NoError(t, err, "unable to read the response body")
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ func (m *JWTValidator) ValidateAndParse(token string) (*jwt.Token, error) {
|
|||||||
if m.options.CredentialsOptional {
|
if m.options.CredentialsOptional {
|
||||||
log.Debugf("no credentials found (CredentialsOptional=true)")
|
log.Debugf("no credentials found (CredentialsOptional=true)")
|
||||||
// No error, just no token (and that is ok given that CredentialsOptional is true)
|
// No error, just no token (and that is ok given that CredentialsOptional is true)
|
||||||
return nil, nil
|
return nil, nil //nolint:nilnil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get here, the required token is missing
|
// If we get here, the required token is missing
|
||||||
@ -219,7 +219,7 @@ func getPemCert(token *jwt.Token, jwks *Jwks) (string, error) {
|
|||||||
return generatePemFromJWK(jwks.Keys[k])
|
return generatePemFromJWK(jwks.Keys[k])
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.New("unable to find appropriate key")
|
return cert, errors.New("unable to find appropriate key")
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatePemFromJWK(jwk JSONWebKey) (string, error) {
|
func generatePemFromJWK(jwk JSONWebKey) (string, error) {
|
||||||
|
@ -141,11 +141,6 @@ func Test_SyncProtocol(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
|
sync, err := client.Sync(context.TODO(), &mgmtProto.EncryptedMessage{
|
||||||
WgPubKey: key.PublicKey().String(),
|
WgPubKey: key.PublicKey().String(),
|
||||||
Body: message,
|
Body: message,
|
||||||
|
@ -79,10 +79,6 @@ func TestAccountManager_GetNetworkMap(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
@ -332,10 +328,6 @@ func TestAccountManager_GetPeerNetwork(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, userId, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
@ -406,14 +398,11 @@ func TestDefaultAccountManager_GetPeer(t *testing.T) {
|
|||||||
|
|
||||||
// two peers one added by a regular user and one with a setup key
|
// two peers one added by a regular user and one with a setup key
|
||||||
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, adminUser, false)
|
setupKey, err := manager.CreateSetupKey(account.Id, "test-key", SetupKeyReusable, time.Hour, nil, 999, adminUser, false)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("error creating setup key")
|
t.Fatal("error creating setup key")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
peerKey1, err := wgtypes.GeneratePrivateKey()
|
peerKey1, err := wgtypes.GeneratePrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/netip"
|
||||||
|
"strconv"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/proto"
|
"github.com/netbirdio/netbird/management/proto"
|
||||||
"github.com/netbirdio/netbird/management/server/activity"
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
"github.com/rs/xid"
|
"github.com/rs/xid"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/netip"
|
|
||||||
"strconv"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -104,12 +105,6 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peerID string,
|
|||||||
|
|
||||||
routesWithPrefix := account.GetRoutesByPrefix(prefix)
|
routesWithPrefix := account.GetRoutesByPrefix(prefix)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if s, ok := status.FromError(err); ok && s.Type() == status.NotFound {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return status.Errorf(status.InvalidArgument, "failed to parse prefix %s", prefix.String())
|
|
||||||
}
|
|
||||||
for _, prefixRoute := range routesWithPrefix {
|
for _, prefixRoute := range routesWithPrefix {
|
||||||
if prefixRoute.Peer == peerID {
|
if prefixRoute.Peer == peerID {
|
||||||
return status.Errorf(status.AlreadyExists, "failed to add route with prefix %s - peer already has this route", prefix.String())
|
return status.Errorf(status.AlreadyExists, "failed to add route with prefix %s - peer already has this route", prefix.String())
|
||||||
|
@ -405,13 +405,13 @@ func (am *DefaultAccountManager) CreatePAT(accountID string, initiatorUserID str
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser := account.Users[targetUserID]
|
targetUser, ok := account.Users[targetUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "targetUser not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
executingUser := account.Users[initiatorUserID]
|
executingUser, ok := account.Users[initiatorUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "user not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,13 +447,13 @@ func (am *DefaultAccountManager) DeletePAT(accountID string, initiatorUserID str
|
|||||||
return status.Errorf(status.NotFound, "account not found: %s", err)
|
return status.Errorf(status.NotFound, "account not found: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser := account.Users[targetUserID]
|
targetUser, ok := account.Users[targetUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return status.Errorf(status.NotFound, "user not found")
|
return status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
executingUser := account.Users[initiatorUserID]
|
executingUser, ok := account.Users[initiatorUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return status.Errorf(status.NotFound, "user not found")
|
return status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,13 +497,13 @@ func (am *DefaultAccountManager) GetPAT(accountID string, initiatorUserID string
|
|||||||
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
|
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser := account.Users[targetUserID]
|
targetUser, ok := account.Users[targetUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "user not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
executingUser := account.Users[initiatorUserID]
|
executingUser, ok := account.Users[initiatorUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "user not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,13 +529,13 @@ func (am *DefaultAccountManager) GetAllPATs(accountID string, initiatorUserID st
|
|||||||
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
|
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser := account.Users[targetUserID]
|
targetUser, ok := account.Users[targetUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "user not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
executingUser := account.Users[initiatorUserID]
|
executingUser, ok := account.Users[initiatorUserID]
|
||||||
if targetUser == nil {
|
if !ok {
|
||||||
return nil, status.Errorf(status.NotFound, "user not found")
|
return nil, status.Errorf(status.NotFound, "user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user