Verified Commit e7f1407a authored by SlevinWasAlreadyTaken's avatar SlevinWasAlreadyTaken 🔥
Browse files

feat(ajwt): improve check security on role/scope

parent 8d5ef739
......@@ -41,6 +41,10 @@ func (c *AccessClaims) IsNotAdminOn(appID string) bool {
return !c.hasRole(appID, adminRoleLabel)
}
func (c *AccessClaims) IsAdminOn(appID string) bool {
return c.hasRole(appID, adminRoleLabel)
}
func (c *AccessClaims) IsAnyAdmin() bool {
return !c.IsNotAdmin()
}
......@@ -63,6 +67,10 @@ func (c *AccessClaims) IsNotDPOOn(appID string) bool {
return !c.hasRole(appID, dpoRoleLabel)
}
func (c *AccessClaims) IsDPOOn(appID string) bool {
return c.hasRole(appID, dpoRoleLabel)
}
func (c *AccessClaims) IsAnyDPO() bool {
return !c.IsNotDPO()
}
......
......@@ -14,7 +14,9 @@ func TestHasRole(t *testing.T) {
}
assert.Equal(t, true, claim.hasRole("2e9394f2-fd9f-4a07-beb5-748c35062cad", adminRoleLabel))
assert.Equal(t, false, claim.IsNotAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPO())
assert.Equal(t, false, claim.IsNotAdmin())
assert.Equal(t, false, claim.IsAnyDPO())
......@@ -29,7 +31,9 @@ func TestHasRole(t *testing.T) {
}
assert.Equal(t, true, claim.hasRole("2e9394f2-fd9f-4a07-beb5-748c35062cad", dpoRoleLabel))
assert.Equal(t, true, claim.IsNotAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsNotDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsNotDPO())
assert.Equal(t, true, claim.IsNotAdmin())
assert.Equal(t, true, claim.IsAnyDPO())
......@@ -44,7 +48,9 @@ func TestHasRole(t *testing.T) {
}
assert.Equal(t, false, claim.hasRole("2e9394f2-fd9f-4a07-beb5-748c35062cad", dpoRoleLabel))
assert.Equal(t, true, claim.IsNotAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPO())
assert.Equal(t, true, claim.IsNotAdmin())
assert.Equal(t, false, claim.IsAnyDPO())
......@@ -61,7 +67,9 @@ func TestHasRole(t *testing.T) {
}
assert.Equal(t, false, claim.hasRole("2e9394f2-fd9f-4a07-beb5-748c35062cad", dpoRoleLabel))
assert.Equal(t, true, claim.IsNotAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPO())
assert.Equal(t, true, claim.IsNotAdmin())
assert.Equal(t, false, claim.IsAnyDPO())
......@@ -80,6 +88,7 @@ func TestHasRole(t *testing.T) {
assert.Equal(t, false, claim.hasRole("2e9394f2-fd9f-4a07-beb5-748c35062cad", dpoRoleLabel))
assert.Equal(t, true, claim.IsNotAdminOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claim.IsDPOOn("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claim.IsNotAdmin())
assert.Equal(t, true, claim.IsNotDPO())
})
......
......@@ -6,7 +6,28 @@ import (
// IsNotUser returns false if claims' scopes defines a user and its subject match given user ID
func (c *AccessClaims) IsNotUser(userID string) bool {
return c.IsNotAnyUser() || c.Subject != userID
return !c.IsUser(userID)
}
// IsUser returns true if claims' scopes defines a user and its subject match given user ID
func (c *AccessClaims) IsUser(userID string) bool {
// check it is at least a user
if c.IsNotAnyUser() {
return false
}
// check the subject is not empty
if c.Subject == "" {
return false
}
// check the input is not empty
if userID == "" {
return false
}
// check if subject and input don't match
if c.Subject != userID {
return false
}
return true
}
// IsAnyUser returns false if claims' scopes defines a user
......@@ -21,7 +42,26 @@ func (c *AccessClaims) IsAnyUser() bool {
// IsNotApp returns false if claims' scopes defines an application and its subject match given app ID
func (c *AccessClaims) IsNotApp(appID string) bool {
return c.IsNotAnyApp() || c.Subject != appID
return !c.IsApp(appID)
}
// IsApp returns true if claims' scopes defines an application and its subject match given app ID
func (c *AccessClaims) IsApp(appID string) bool {
if c.IsNotAnyApp() {
return false
}
// check the subject is not empty
if c.Subject == "" {
return false
}
// check the input is not empty
if appID == "" {
return false
}
if c.Subject != appID {
return false
}
return true
}
// IsNotAnyApp returns false if claims' scopes defines an application
......@@ -36,7 +76,26 @@ func (c *AccessClaims) IsAnyApp() bool {
// IsNotService returns false if claims' scopes defines a service and its subject match given service ID
func (c *AccessClaims) IsNotService(serviceID string) bool {
return c.IsNotAnyService() || c.Subject != serviceID
return !c.IsService(serviceID)
}
// IsService returns true if claims' scopes defines a service and its subject match given service ID
func (c *AccessClaims) IsService(serviceID string) bool {
if c.IsNotAnyService() {
return false
}
// check the subject is not empty
if c.Subject == "" {
return false
}
// check the input is not empty
if serviceID == "" {
return false
}
if c.Subject != serviceID {
return false
}
return true
}
// IsNotAnyService returns false if claims' scopes defines a service
......@@ -51,7 +110,18 @@ func (c *AccessClaims) IsAnyService() bool {
// IsNotMisadmin returns false if claims' scopes defines a user & a misadmin
func (c *AccessClaims) IsNotMisadmin() bool {
return c.IsNotAnyUser() || !c.hasScope(misadminScope)
return !c.IsMisadmin()
}
// IsMisadmin returns true if claims' scopes defines a user & a misadmin
func (c *AccessClaims) IsMisadmin() bool {
if c.IsNotAnyUser() {
return false
}
if !c.hasScope(misadminScope) {
return false
}
return true
}
// IsMisadminScope return true if given scope string is considered as a misadmin scope.
......
......@@ -7,13 +7,14 @@ import (
)
func TestScope(t *testing.T) {
t.Run("test IsNotUser", func(t *testing.T) {
t.Run("test Is(Not)User", func(t *testing.T) {
// 1. the expected user
claims := AccessClaims{
Scope: "openid user rol:1:2",
Subject: "18b88d48-ad48-43b9-a323-eab1de68b280",
}
assert.Equal(t, false, claims.IsNotUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
assert.Equal(t, true, claims.IsUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
// 2. not the expected user
claims = AccessClaims{
......@@ -21,6 +22,7 @@ func TestScope(t *testing.T) {
Subject: "another-uuid",
}
assert.Equal(t, true, claims.IsNotUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
assert.Equal(t, false, claims.IsUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
// 3. not even a user
claims = AccessClaims{
......@@ -28,15 +30,33 @@ func TestScope(t *testing.T) {
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, true, claims.IsNotUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
assert.Equal(t, false, claims.IsUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
// 4. empty subject
claims = AccessClaims{
Scope: "openid user rol:1:2",
Subject: "",
}
assert.Equal(t, true, claims.IsNotUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
assert.Equal(t, false, claims.IsUser("18b88d48-ad48-43b9-a323-eab1de68b280"))
// 5. empty input
claims = AccessClaims{
Scope: "openid user rol:1:2",
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, true, claims.IsNotUser(""))
assert.Equal(t, false, claims.IsUser(""))
})
t.Run("test IsNotApp", func(t *testing.T) {
// 1. the expeted application
t.Run("test Is(Not)App", func(t *testing.T) {
// 1. the expected application
claims := AccessClaims{
Scope: "openid application",
Subject: "00000000-1111-2222-3333-444444444444",
}
assert.Equal(t, false, claims.IsNotApp("00000000-1111-2222-3333-444444444444"))
assert.Equal(t, true, claims.IsApp("00000000-1111-2222-3333-444444444444"))
// 2. not the expected app
claims = AccessClaims{
......@@ -44,6 +64,7 @@ func TestScope(t *testing.T) {
Subject: "another_uuid",
}
assert.Equal(t, true, claims.IsNotApp("00000000-1111-2222-3333-444444444444"))
assert.Equal(t, false, claims.IsApp("00000000-1111-2222-3333-444444444444"))
// 3. not even an application
claims = AccessClaims{
......@@ -51,15 +72,33 @@ func TestScope(t *testing.T) {
Subject: "18b88d48-ad48-43b9-a323-eab1de68b280",
}
assert.Equal(t, true, claims.IsNotApp("00000000-1111-2222-3333-444444444444"))
assert.Equal(t, false, claims.IsApp("00000000-1111-2222-3333-444444444444"))
// 4. empty subject
claims = AccessClaims{
Scope: "openid application",
Subject: "",
}
assert.Equal(t, true, claims.IsNotApp("00000000-1111-2222-3333-444444444444"))
assert.Equal(t, false, claims.IsApp("00000000-1111-2222-3333-444444444444"))
// 5. empty input
claims = AccessClaims{
Scope: "openid application",
Subject: "00000000-1111-2222-3333-444444444444",
}
assert.Equal(t, true, claims.IsNotApp(""))
assert.Equal(t, false, claims.IsApp(""))
})
t.Run("test IsNotService", func(t *testing.T) {
// 1. the expeted service
t.Run("test Is(Not)Service", func(t *testing.T) {
// 1. the expected service
claims := AccessClaims{
Scope: "openid service",
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, false, claims.IsNotService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, true, claims.IsService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
// 2. not the expected service
claims = AccessClaims{
......@@ -67,6 +106,7 @@ func TestScope(t *testing.T) {
Subject: "databox-backend",
}
assert.Equal(t, true, claims.IsNotService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claims.IsService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
// 3. not even a service
claims = AccessClaims{
......@@ -74,27 +114,55 @@ func TestScope(t *testing.T) {
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, true, claims.IsNotService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
assert.Equal(t, false, claims.IsService("2e9394f2-fd9f-4a07-beb5-748c35062cad"))
// 4. empty subject
claims = AccessClaims{
Scope: "openid service",
Subject: "",
}
assert.Equal(t, true, claims.IsNotService("00000000-1111-2222-3333-444444444444"))
assert.Equal(t, false, claims.IsService("00000000-1111-2222-3333-444444444444"))
// 5. empty input
claims = AccessClaims{
Scope: "openid service",
Subject: "00000000-1111-2222-3333-444444444444",
}
assert.Equal(t, true, claims.IsNotService(""))
assert.Equal(t, false, claims.IsService(""))
})
t.Run("test IsNotMisadmin", func(t *testing.T) {
t.Run("test Is(Not)Misadmin", func(t *testing.T) {
// 1. a valid misadmin
claims := AccessClaims{
Scope: "openid user misadmin",
}
assert.Equal(t, false, claims.IsNotMisadmin())
assert.Equal(t, true, claims.IsMisadmin())
// 2. an invalid misadmin - missing user scope
claims = AccessClaims{
Scope: "openid misadmin",
}
assert.Equal(t, true, claims.IsNotMisadmin())
assert.Equal(t, false, claims.IsMisadmin())
// 3. not even a misadmin
// 3. not even a user
claims = AccessClaims{
Scope: "openid service",
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, true, claims.IsNotMisadmin())
assert.Equal(t, false, claims.IsMisadmin())
// 3. a user without misadmin scope
claims = AccessClaims{
Scope: "openid user charlatan",
Subject: "2e9394f2-fd9f-4a07-beb5-748c35062cad",
}
assert.Equal(t, true, claims.IsNotMisadmin())
assert.Equal(t, false, claims.IsMisadmin())
})
t.Run("test IsMisadminScope", func(t *testing.T) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment