Skip to content

Commit 44461f8

Browse files
committed
feat: Refactor and enhance user initialization and role handling.
This update introduces user initialization via a YAML file and role-based scope encryption for tokens. It also refactors database collection access across repositories and consolidates password handling and validation into utilities. Additionally, it includes new CLI and HTTP stream handling functionality.
1 parent 83edbd6 commit 44461f8

27 files changed

Lines changed: 425 additions & 117 deletions

File tree

DockerfileBuild

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ COPY . .
1717
RUN go build -o wireguard-api cmd/server/main.go
1818
RUN go build -o api-key-generator cmd/generator/api_secret/main.go
1919
RUN go build -o wireguard-tools cmd/cli/main.go
20+
RUN go build -o wireguard-stream cmd/stream/main.go
2021

2122
FROM alpine:latest
2223

@@ -29,6 +30,8 @@ RUN mkdir -p /output
2930
COPY --from=builder /app/wireguard-api /bin/wireguard-api
3031
COPY --from=builder /app/api-key-generator /bin/api-key-generator
3132
COPY --from=builder /app/wireguard-tools /bin/wireguard-tools
33+
COPY --from=builder /app/wireguard-stream /bin/wireguard-stream
3234
COPY --from=builder /app/scripts/docker/compiler/build /bin/build
3335

36+
3437
CMD ["sh", "/bin/build"]

cmd/server/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"github.com/softwareplace/wireguard-api/pkg/domain/db"
55
"github.com/softwareplace/wireguard-api/pkg/domain/service/peer"
6+
"github.com/softwareplace/wireguard-api/pkg/domain/service/user"
67
"github.com/softwareplace/wireguard-api/pkg/handlers"
78
"github.com/softwareplace/wireguard-api/pkg/router"
89
)
@@ -12,5 +13,6 @@ func main() {
1213
api := router.GetApiRouterHandler()
1314
handlers.Init(api)
1415
peer.GetService().Load()
16+
user.GetService().Init()
1517
api.StartServer()
1618
}

dev/conf.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ current-server: development
33
current-profile: eliasmeireles
44
servers:
55
- name: development
6-
host: http://localhost:8080/api/private-network/v1
6+
host: http://localhost:1080/api/private-network/v1/
77
apiKey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnQiOiJTb2Z0d2FyZSBQbGFjZSBDTyIsImV4cCI6MjA1MTYwMzA2Mywia2V5IjoibDNWcEovQmY1eTZhcVRpZGxZUy9meTZoY2lObTNqRzdvQWxHS2kzZVU5NkNWeHZITFVpeDl3PT0ifQ.2YJ3aBYT_3SgqTqhEyNJwK6iglCYCHvPRbCWc4MKzp0
88
description: Development server
99
profiles:
1010
- name: eliasmeireles
1111
description: Development server
12-
authorization-id: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzYzNDY4NDEsInJlcXVlc3QiOiJkUkpDcENtY1RST2JpRmdKVHl0dVpIdjJFZnRkaDd2aGdzdzNhb0xwNTJQblVvWWZhTm9rdytHRUltLzdWRFZKIiwic2NvcGUiOiJhRXMyUVk4UW1HaWRUVVh6cGlEY1IzaVJ5dk9xIn0.chRBSwLtJ5dm9-z6ZHIZdl6pb-43jUnLcqlYwBBlHtM
13-
expires: "1736346841"
12+
authorization-id: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzYzNTUxNjMsInJlcXVlc3QiOiJrRG5ud2wzd3hteHNiRXo5eFpwT1RTNWUxTmFCakluaC9VUEdlWHpJWUZSVlBKRG11OXBRdW1ENHBXZTlrWll4Iiwic2NvcGUiOiI5WkVrVkJhdXNSemZFTUlMTWsxV3JDOXM3dXhCVkY3aVNYZk8wMWpRY1E9PSJ9.dDheBDMI1q6z35xzO_Zx_oFSprOFrul6kfV9wvS_spw
13+
expires: "1736355163"

dev/init.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
user:
2+
username: my-username
3+
email: user@email.com
4+
password: ynT9558iiMga&ayTVGs3Gc6ug1
5+
status: ACTIVE
6+
roles:
7+
- "resource:peers:get:peer"
8+
- "resource:api-secret:generate"
9+
- "resource:users:update:user"
10+
- "resource:users:create:user"
11+

pkg/auth/access_validation.go

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
11
package auth
22

33
import (
4-
"github.com/softwareplace/wireguard-api/pkg/domain/repository/user"
5-
"github.com/softwareplace/wireguard-api/pkg/domain/service/security"
64
"github.com/softwareplace/wireguard-api/pkg/handlers/request"
5+
"github.com/softwareplace/wireguard-api/pkg/handlers/shared"
76
"github.com/softwareplace/wireguard-api/pkg/models"
87
"log"
98
"net/http"
10-
"sync"
119
)
1210

13-
var (
14-
openPath []string
15-
openPathLock sync.RWMutex
16-
apiSecurityService = security.GetApiSecurityService()
17-
usersRepo = user.Repository()
18-
)
19-
20-
func AddOpenPath(path string) {
21-
openPathLock.Lock()
22-
defer openPathLock.Unlock()
23-
openPath = append(openPath, path)
24-
}
25-
2611
func AccessValidation(next http.Handler) http.Handler {
2712
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2813
openPathLock.RLock()
@@ -42,12 +27,52 @@ func AccessValidation(next http.Handler) http.Handler {
4227
if !success {
4328
return
4429
}
30+
31+
if !hasResourceAccess(w, r, ctx) {
32+
return
33+
}
4534
}
4635

4736
next.ServeHTTP(w, ctx.Request)
4837
})
4938
}
5039

40+
func hasResourceAccess(w http.ResponseWriter, r *http.Request, ctx request.ApiRequestContext) bool {
41+
userRoles, err := ctx.GetRoles()
42+
43+
if err != nil {
44+
shared.MakeErrorResponse(w, "You are not allowed to access this resource", http.StatusUnauthorized)
45+
return false
46+
}
47+
48+
accessRoles, hasRoles := GetRolesForPath(r)
49+
50+
if !hasRoles {
51+
shared.MakeErrorResponse(w, "You are not allowed to access this resource", http.StatusUnauthorized)
52+
return false
53+
}
54+
55+
hasAccess := false
56+
57+
for _, userRole := range userRoles {
58+
for _, accessRole := range accessRoles {
59+
if userRole == accessRole {
60+
hasAccess = true
61+
break
62+
}
63+
}
64+
if hasAccess {
65+
break
66+
}
67+
}
68+
69+
if !hasAccess {
70+
shared.MakeErrorResponse(w, "You are not allowed to access this resource", http.StatusUnauthorized)
71+
return false
72+
}
73+
return true
74+
}
75+
5176
func _nextValidation(ctx *request.ApiRequestContext) (*models.User, bool) {
5277
accessContext := ctx.GetAccessContext()
5378
userData, err := usersRepo.FindUserBySalt(accessContext.AccessId)

pkg/auth/data.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package auth
2+
3+
import (
4+
"github.com/softwareplace/wireguard-api/pkg/domain/repository/user"
5+
"github.com/softwareplace/wireguard-api/pkg/domain/service/security"
6+
"net/http"
7+
"sync"
8+
)
9+
10+
var (
11+
roles = make(map[string][]string)
12+
openPath []string
13+
openPathLock sync.RWMutex
14+
apiSecurityService = security.GetApiSecurityService()
15+
usersRepo = user.Repository()
16+
)
17+
18+
func AddOpenPath(path string) {
19+
openPathLock.Lock()
20+
defer openPathLock.Unlock()
21+
openPath = append(openPath, path)
22+
}
23+
24+
func AddRoles(path string, requiredRoles ...string) {
25+
if len(requiredRoles) > 0 {
26+
roles[path] = requiredRoles
27+
}
28+
}
29+
30+
func GetRolesForPath(r *http.Request) ([]string, bool) {
31+
path := r.Method + "::" + r.URL.Path
32+
if roles[path] != nil {
33+
return roles[path], true
34+
}
35+
return nil, false
36+
}

pkg/domain/repository/peer/peer_repository.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package peer
33
import (
44
"context"
55
"errors"
6-
"github.com/softwareplace/wireguard-api/pkg/domain/db"
76
"github.com/softwareplace/wireguard-api/pkg/models"
87
"github.com/softwareplace/wireguard-api/pkg/utils/date"
98
"go.mongodb.org/mongo-driver/bson"
@@ -13,7 +12,7 @@ import (
1312
)
1413

1514
func (r *repositoryImpl) SaveAll(peers []models.Peer) error {
16-
database := db.GetDB().Collection("peers")
15+
database := r.collection()
1716

1817
for _, peer := range peers {
1918
filter := bson.M{"fileName": peer.FileName}
@@ -48,7 +47,7 @@ func (r *repositoryImpl) SaveAll(peers []models.Peer) error {
4847
}
4948

5049
func (r *repositoryImpl) Save(peer models.Peer) error {
51-
database := db.GetDB().Collection("peers")
50+
database := r.collection()
5251
nowToString := date.NowToString()
5352
peer.UpdatedAt = nowToString
5453
peer.CreatedAt = nowToString
@@ -63,7 +62,7 @@ func (r *repositoryImpl) Save(peer models.Peer) error {
6362
}
6463

6564
func (r *repositoryImpl) GetAvailablePeer() (*models.Peer, error) {
66-
database := db.GetDB().Collection("peers")
65+
database := r.collection()
6766

6867
var peer models.Peer
6968
err := database.FindOne(context.Background(), bson.M{}).Decode(&peer)
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
package peer
22

3-
import "github.com/softwareplace/wireguard-api/pkg/models"
3+
import (
4+
"github.com/softwareplace/wireguard-api/pkg/domain/db"
5+
"github.com/softwareplace/wireguard-api/pkg/models"
6+
"go.mongodb.org/mongo-driver/mongo"
7+
)
48

59
type Repository interface {
610
SaveAll(peers []models.Peer) error
711
Save(peer models.Peer) error
812
GetAvailablePeer() (*models.Peer, error)
913
}
1014

11-
type repositoryImpl struct{}
15+
type repositoryImpl struct {
16+
database *mongo.Database
17+
}
1218

1319
func GetRepository() Repository {
14-
return &repositoryImpl{}
20+
return &repositoryImpl{
21+
database: db.GetDB(),
22+
}
23+
}
24+
25+
func (r *repositoryImpl) collection() *mongo.Collection {
26+
return r.database.Collection("peers")
1527
}

pkg/domain/repository/user/users_repository.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package user
22

33
import (
4+
"github.com/softwareplace/wireguard-api/pkg/domain/db"
45
"github.com/softwareplace/wireguard-api/pkg/models"
6+
"go.mongodb.org/mongo-driver/mongo"
57
)
68

79
type UsersRepository interface {
@@ -14,8 +16,15 @@ type UsersRepository interface {
1416
}
1517

1618
type usersRepositoryImpl struct {
19+
database *mongo.Database
20+
}
21+
22+
func (r *usersRepositoryImpl) collection() *mongo.Collection {
23+
return r.database.Collection("users")
1724
}
1825

1926
func Repository() UsersRepository {
20-
return &usersRepositoryImpl{}
27+
return &usersRepositoryImpl{
28+
database: db.GetDB(),
29+
}
2130
}

pkg/domain/repository/user/users_repository_impl.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@ package user
33
import (
44
"context"
55
"fmt"
6-
"github.com/softwareplace/wireguard-api/pkg/domain/db"
76
"github.com/softwareplace/wireguard-api/pkg/models"
87
"github.com/softwareplace/wireguard-api/pkg/utils/date"
98
"go.mongodb.org/mongo-driver/bson"
109
"log"
1110
)
1211

13-
func (impl *usersRepositoryImpl) Save(user models.User) error {
14-
collection := db.GetDB().Collection("users")
12+
func (r *usersRepositoryImpl) Save(user models.User) error {
13+
collection := r.collection()
1514

1615
nowToString := date.NowToString()
1716
user.CreatedAt = nowToString
@@ -21,8 +20,8 @@ func (impl *usersRepositoryImpl) Save(user models.User) error {
2120
return err
2221
}
2322

24-
func (impl *usersRepositoryImpl) Update(user models.User) error {
25-
collection := db.GetDB().Collection("users")
23+
func (r *usersRepositoryImpl) Update(user models.User) error {
24+
collection := r.collection()
2625
user.UpdatedAt = date.NowToString()
2726

2827
filter := bson.M{"_id": user.Id}
@@ -31,8 +30,8 @@ func (impl *usersRepositoryImpl) Update(user models.User) error {
3130
return err
3231
}
3332

34-
func (impl *usersRepositoryImpl) FindUserBySalt(salt string) (*models.User, error) {
35-
collection := db.GetDB().Collection("users")
33+
func (r *usersRepositoryImpl) FindUserBySalt(salt string) (*models.User, error) {
34+
collection := r.collection()
3635
var currentUser models.User
3736

3837
err := collection.FindOne(context.Background(), map[string]interface{}{
@@ -46,8 +45,8 @@ func (impl *usersRepositoryImpl) FindUserBySalt(salt string) (*models.User, erro
4645
return &currentUser, nil
4746
}
4847

49-
func (impl *usersRepositoryImpl) FindUserByEmail(email string) (*models.User, error) {
50-
collection := db.GetDB().Collection("users")
48+
func (r *usersRepositoryImpl) FindUserByEmail(email string) (*models.User, error) {
49+
collection := r.collection()
5150
var user models.User
5251
err := collection.FindOne(context.Background(), map[string]interface{}{
5352
"email": email,
@@ -58,8 +57,8 @@ func (impl *usersRepositoryImpl) FindUserByEmail(email string) (*models.User, er
5857
return &user, nil
5958
}
6059

61-
func (impl *usersRepositoryImpl) FindUserByUsername(username string) (*models.User, error) {
62-
collection := db.GetDB().Collection("users")
60+
func (r *usersRepositoryImpl) FindUserByUsername(username string) (*models.User, error) {
61+
collection := r.collection()
6362
var user models.User
6463
err := collection.FindOne(context.Background(), map[string]interface{}{
6564
"username": username,
@@ -70,14 +69,14 @@ func (impl *usersRepositoryImpl) FindUserByUsername(username string) (*models.Us
7069
return &user, nil
7170
}
7271

73-
func (impl *usersRepositoryImpl) FindUserByUsernameOrEmail(username string, email string) (*models.User, error) {
72+
func (r *usersRepositoryImpl) FindUserByUsernameOrEmail(username string, email string) (*models.User, error) {
7473
if username != "" {
75-
return impl.FindUserByUsername(username)
74+
return r.FindUserByUsername(username)
7675

7776
}
7877

7978
if email != "" {
80-
return impl.FindUserByEmail(email)
79+
return r.FindUserByEmail(email)
8180
}
8281

8382
return nil, fmt.Errorf("username or email must be provided")

0 commit comments

Comments
 (0)