Skip to content

Commit

Permalink
feat: added srv test coverage and remove unused funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
Wil Simpson committed Dec 5, 2024
1 parent 2e421b7 commit a591fd0
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 38 deletions.
69 changes: 32 additions & 37 deletions pkg/srv/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"time"

"github.com/ShatteredRealms/go-common-service/pkg/auth"
"github.com/ShatteredRealms/go-common-service/pkg/config"
"github.com/ShatteredRealms/go-common-service/pkg/log"
"github.com/WilSimpson/gocloak/v13"
Expand Down Expand Up @@ -108,39 +107,35 @@ func (srvCtx *Context) CreateRoles(ctx context.Context, roles *[]*gocloak.Role)
return errs
}

// GetUserId gets the user id from the username or returns the given id if it is not empty
func (srvCtx *Context) GetUserId(
ctx context.Context,
id string,
username string,
) (string, error) {
ctx, span := srvCtx.Tracer.Start(ctx, "target.get_user_id")
defer span.End()

ownerId := id
if ownerId == "" {
jwt, err := srvCtx.GetJWT(ctx)
if err != nil {
return "", fmt.Errorf("get user id: %w", err)
}
resp, err := srvCtx.KeycloakClient.GetUsers(
ctx,
jwt.AccessToken,
srvCtx.Config.Keycloak.Realm,
gocloak.GetUsersParams{
Exact: gocloak.BoolP(true),
Username: gocloak.StringP(username),
},
)
if err != nil {
return "", fmt.Errorf("keycloak get users: %v", err)
}
if len(resp) == 0 || len(resp) > 1 {
return "", auth.ErrDoesNotExist
}

ownerId = *resp[0].ID
}

return ownerId, nil
}
// // ValidateUserExists checks if a user exists in Keycloak. If the user does not exist it returns
// // auth.ErrDoesNotExist. Otherwise, it returns nil. Other errors are possible.
// func (srvCtx *Context) ValidateUserExists(
// ctx context.Context,
// id string,
// ) error {
// ctx, span := srvCtx.Tracer.Start(ctx, "target.get_user_id")
// defer span.End()
//
// jwt, err := srvCtx.GetJWT(ctx)
// if err != nil {
// return fmt.Errorf("fetch client token: %w", err)
// }
// resp, err := srvCtx.KeycloakClient.GetUsers(
// ctx,
// jwt.AccessToken,
// srvCtx.Config.Keycloak.Realm,
// gocloak.GetUsersParams{
// Exact: gocloak.BoolP(true),
// IDPUserID: gocloak.StringP(id),
// },
// )
// if err != nil {
// return fmt.Errorf("keycloak get users: %v", err)
// }
//
// if len(resp) == 0 || len(resp) > 1 {
// return auth.ErrDoesNotExist
// }
//
// return nil
// }
103 changes: 103 additions & 0 deletions pkg/srv/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package srv_test

import (
"strings"

"github.com/WilSimpson/gocloak/v13"
"github.com/go-faker/faker/v4"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sirupsen/logrus"

"github.com/ShatteredRealms/go-common-service/pkg/config"
"github.com/ShatteredRealms/go-common-service/pkg/log"
"github.com/ShatteredRealms/go-common-service/pkg/srv"
)

var _ = Describe("Context", func() {
var context *srv.Context
var cfg *config.BaseConfig
var logLevel logrus.Level
BeforeEach(func() {
Expect(faker.FakeData(&logLevel)).To(Succeed())
cfg = &config.BaseConfig{
Keycloak: kcCfg,
LogLevel: logLevel,
}
context = srv.NewContext(cfg, faker.Username())
Expect(context).NotTo(BeNil())
})

Describe("NewContext", func() {
It("should setup keycloak", func() {
Expect(context.KeycloakClient).NotTo(BeNil())
})
It("should setup tracer", func() {
Expect(context.Tracer).NotTo(BeNil())
})
It("should set the log level", func() {
Expect(log.Logger.Level).To(Equal(logLevel))
})
})

Describe("GetJwt", func() {
When("valid keycloak credentials are provided", func() {
It("should return a valid JWT", func(ctx SpecContext) {
jwt, err := context.GetJWT(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(jwt).NotTo(BeNil())
Expect(jwt.AccessToken).NotTo(BeEmpty())
Expect(strings.Split(jwt.AccessToken, ".")).To(HaveLen(3))
})
It("should should cache the JWT", func(ctx SpecContext) {
jwt, err := context.GetJWT(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(jwt).NotTo(BeNil())
Expect(jwt.AccessToken).NotTo(BeEmpty())
Expect(strings.Split(jwt.AccessToken, ".")).To(HaveLen(3))
jwt2, err := context.GetJWT(ctx)
Expect(err).NotTo(HaveOccurred())
Expect(jwt).To(Equal(jwt2))
})
})
When("invalid keycloak credentials are provided", func() {
It("should return an error", func(ctx SpecContext) {
cfg.Keycloak.ClientSecret = faker.Password()
context = srv.NewContext(cfg, faker.Username())
jwt, err := context.GetJWT(ctx)
Expect(err).To(HaveOccurred())
Expect(jwt).To(BeNil())
})
})
})

Describe("CreateRoles", func() {
var roles []*gocloak.Role
BeforeEach(func() {
roles = []*gocloak.Role{
{
Name: gocloak.StringP(faker.Username()),
ClientRole: gocloak.BoolP(true),
ContainerID: new(string),
Description: gocloak.StringP(faker.Sentence()),
},
}
})
When("valid keycloak credentials are provided", func() {
It("should create client roles if the do not exist", func(ctx SpecContext) {
Expect(context.CreateRoles(ctx, &roles)).To(Succeed())
})
It("should ignore errors if they already exist", func(ctx SpecContext) {
Expect(context.CreateRoles(ctx, &roles)).To(Succeed())
Expect(context.CreateRoles(ctx, &roles)).To(Succeed())
})
})
When("invalid keycloak credentials are provided", func() {
It("should return an error", func(ctx SpecContext) {
cfg.Keycloak.ClientSecret = faker.Password()
context = srv.NewContext(cfg, faker.Username())
Expect(context.CreateRoles(ctx, nil)).To(HaveOccurred())
})
})
})
})
136 changes: 135 additions & 1 deletion pkg/srv/srv_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,147 @@
package srv_test

import (
"context"
"fmt"
"strings"
"testing"

"github.com/ShatteredRealms/go-common-service/pkg/config"
"github.com/ShatteredRealms/go-common-service/pkg/log"
"github.com/ShatteredRealms/go-common-service/pkg/testsro"
"github.com/WilSimpson/gocloak/v13"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sirupsen/logrus/hooks/test"
"google.golang.org/grpc/metadata"
)

var (
keycloak *gocloak.GoCloak

admin = gocloak.User{
ID: new(string),
Username: gocloak.StringP("testadmin"),
Enabled: gocloak.BoolP(true),
Totp: gocloak.BoolP(true),
EmailVerified: gocloak.BoolP(true),
FirstName: gocloak.StringP("adminfirstname"),
LastName: gocloak.StringP("adminlastname"),
Email: gocloak.StringP("[email protected]"),
Credentials: &[]gocloak.CredentialRepresentation{
{
Temporary: gocloak.BoolP(false),
Type: gocloak.StringP("password"),
Value: gocloak.StringP("Password1!"),
},
},
}

clientToken *gocloak.JWT
adminToken *gocloak.JWT

incAdminCtx context.Context

kcCfg = config.KeycloakConfig{
Realm: "default",
Id: "738a426a-da91-4b16-b5fc-92d63a22eb76",
ClientId: "sro-character",
ClientSecret: "**********",
}
)

func TestSrv(t *testing.T) {
var keycloakCloseFunc func() error

SynchronizedBeforeSuite(func() []byte {
log.Logger, _ = test.NewNullLogger()
var host string
var err error
keycloakCloseFunc, host, err = testsro.SetupKeycloakWithDocker()
kcCfg.BaseURL = host
Expect(err).NotTo(HaveOccurred())
Expect(host).NotTo(BeNil())

keycloak = gocloak.NewClient(host)
Expect(keycloak).NotTo(BeNil())

clientToken, err := keycloak.LoginClient(
context.Background(),
kcCfg.ClientId,
kcCfg.ClientSecret,
kcCfg.Realm,
)
Expect(err).NotTo(HaveOccurred())

*admin.ID, err = keycloak.CreateUser(context.Background(), clientToken.AccessToken, kcCfg.Realm, admin)
Expect(err).NotTo(HaveOccurred())

saRole, err := keycloak.GetRealmRole(context.Background(), clientToken.AccessToken, kcCfg.Realm, "super admin")
Expect(err).NotTo(HaveOccurred())

err = keycloak.AddRealmRoleToUser(
context.Background(),
clientToken.AccessToken,
kcCfg.Realm,
*admin.ID,
[]gocloak.Role{*saRole},
)

out := fmt.Sprintf("%s", host)

return []byte(out)
}, func(data []byte) {
log.Logger, _ = test.NewNullLogger()
splitData := strings.Split(string(data), "\n")
Expect(splitData).To(HaveLen(1))

host := splitData[0]
kcCfg.BaseURL = host

keycloak = gocloak.NewClient(string(host))
Expect(keycloak).NotTo(BeNil())

clientToken, err := keycloak.LoginClient(
context.Background(),
kcCfg.ClientId,
kcCfg.ClientSecret,
kcCfg.Realm,
)
Expect(err).NotTo(HaveOccurred())
adminToken, err = keycloak.GetToken(context.Background(), kcCfg.Realm, gocloak.TokenOptions{
ClientID: &kcCfg.ClientId,
ClientSecret: &kcCfg.ClientSecret,
GrantType: gocloak.StringP("password"),
Username: admin.Username,
Password: gocloak.StringP("Password1!"),
})
Expect(err).NotTo(HaveOccurred())

admins, err := keycloak.GetUsers(
context.Background(),
clientToken.AccessToken,
kcCfg.Realm,
gocloak.GetUsersParams{Username: admin.Username},
)
Expect(err).NotTo(HaveOccurred())
Expect(admins).To(HaveLen(1))
admin = *admins[0]

md := metadata.New(
map[string]string{
"authorization": "Bearer " + adminToken.AccessToken,
},
)
incAdminCtx = metadata.NewIncomingContext(context.Background(), md)
})

SynchronizedAfterSuite(func() {
}, func() {
if keycloakCloseFunc != nil {
keycloakCloseFunc()
}
})

RegisterFailHandler(Fail)
RunSpecs(t, "Srv Suite")
RunSpecs(t, "Auth Suite")
}
4 changes: 4 additions & 0 deletions pkg/testsro/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func SetupKeycloakWithDocker() (closeFn func() error, host string, err error) {
return
}

if pool.Client.Ping() != nil {
return nil, "", errors.New("docker not running")
}

pool.MaxWait = time.Second * 10
fnConfig := func(config *docker.HostConfig) {
config.AutoRemove = true
Expand Down

0 comments on commit a591fd0

Please sign in to comment.