Skip to content

Commit

Permalink
Merge 382dddf into b3c58c6
Browse files Browse the repository at this point in the history
  • Loading branch information
fperot74 committed Mar 9, 2020
2 parents b3c58c6 + 382dddf commit 8e2ce66
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 105 deletions.
15 changes: 7 additions & 8 deletions api/account/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ func TestConvertToAPIAccount(t *testing.T) {
})

var attributes = kc.Attributes{
"phoneNumber": []string{"+41221234567"},
"gender": []string{"M"},
"birthDate": []string{"15.02.1920"},
"locale": []string{"fr"},
"phoneNumberVerified": []string{"true"},
constants.AttrbPhoneNumber: []string{"+41221234567"},
constants.AttrbGender: []string{"M"},
constants.AttrbBirthDate: []string{"15.02.1920"},
constants.AttrbLocale: []string{"fr"},
constants.AttrbPhoneNumberVerified: []string{"true"},
}

t.Run("Check attributes are copied", func(t *testing.T) {
Expand Down Expand Up @@ -71,9 +71,8 @@ func TestConvertToKCUser(t *testing.T) {
var locale = "fr"
apiUser = AccountRepresentation{PhoneNumber: &phoneNumber, Locale: &locale}
var kcUser = ConvertToKCUser(apiUser)
var kcAttributes = *kcUser.Attributes
assert.Equal(t, phoneNumber, kcAttributes["phoneNumber"][0])
assert.Equal(t, locale, kcAttributes["locale"][0])
assert.Equal(t, phoneNumber, *kcUser.GetAttributeString(constants.AttrbPhoneNumber))
assert.Equal(t, locale, *kcUser.GetAttributeString(constants.AttrbLocale))
}

func TestValidateAccountRepresentation(t *testing.T) {
Expand Down
8 changes: 4 additions & 4 deletions api/kyc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,18 @@ func (u *UserRepresentation) ImportFromKeycloak(kcUser *kc.UserRepresentation) {

if kcUser.Attributes != nil {
var m = *kcUser.Attributes
if value, ok := m["phoneNumber"]; ok && len(value) > 0 {
if value, ok := m[constants.AttrbPhoneNumber]; ok && len(value) > 0 {
phoneNumber = &value[0]
}
if value, ok := m["phoneNumberVerified"]; ok && len(value) > 0 {
if value, ok := m[constants.AttrbPhoneNumberVerified]; ok && len(value) > 0 {
if verified, err := strconv.ParseBool(value[0]); err == nil {
phoneNumberVerified = &verified
}
}
if value, ok := m["gender"]; ok && len(value) > 0 {
if value, ok := m[constants.AttrbGender]; ok && len(value) > 0 {
gender = &value[0]
}
if value, ok := m["birthDate"]; ok && len(value) > 0 {
if value, ok := m[constants.AttrbBirthDate]; ok && len(value) > 0 {
birthdate = &value[0]
}
}
Expand Down
14 changes: 8 additions & 6 deletions api/kyc/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package apikyc
import (
"testing"

"github.com/cloudtrust/keycloak-bridge/internal/constants"

kc "github.com/cloudtrust/keycloak-client"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -47,10 +49,10 @@ func createValidKeycloakUser() kc.UserRepresentation {
lastName = "El-Bichoun"
email = "marcel.bichon@elca.ch"
attributes = kc.Attributes{
"gender": []string{"M"},
"phoneNumber": []string{"00 33 686 550011"},
"phoneNumberVerified": []string{"true"},
"birthDate": []string{"29.02.2020"},
constants.AttrbGender: []string{"M"},
constants.AttrbPhoneNumber: []string{"00 33 686 550011"},
constants.AttrbPhoneNumberVerified: []string{"true"},
constants.AttrbBirthDate: []string{"29.02.2020"},
}
)

Expand Down Expand Up @@ -119,9 +121,9 @@ func TestExportToKeycloak(t *testing.T) {
assert.Equal(t, user.FirstName, kcUser.FirstName)
assert.Equal(t, user.LastName, kcUser.LastName)
assert.Equal(t, user.EmailAddress, kcUser.Email)
assert.Equal(t, *user.PhoneNumber, (*kcUser.Attributes)["phoneNumber"][0])
assert.Equal(t, *user.PhoneNumber, *kcUser.GetAttributeString(constants.AttrbPhoneNumber))
assert.False(t, *kcUser.EmailVerified)
assert.Equal(t, "false", (*kcUser.Attributes)["phoneNumberVerified"][0])
assert.Equal(t, "false", *kcUser.GetAttributeString(constants.AttrbPhoneNumberVerified))
assert.True(t, *kcUser.Enabled)
})
}
Expand Down
45 changes: 17 additions & 28 deletions api/management/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package management_api

import (
"encoding/json"
"strconv"

errorhandler "github.com/cloudtrust/common-service/errors"

Expand Down Expand Up @@ -188,46 +187,36 @@ func ConvertToAPIUser(userKc kc.UserRepresentation) UserRepresentation {
userRep.CreatedTimestamp = userKc.CreatedTimestamp

if userKc.Attributes != nil {
var m = *userKc.Attributes

if m["phoneNumber"] != nil {
var phoneNumber = m["phoneNumber"][0]
userRep.PhoneNumber = &phoneNumber
if value := userKc.GetAttributeString(constants.AttrbPhoneNumber); value != nil {
userRep.PhoneNumber = value
}

if m["label"] != nil {
var label = m["label"][0]
userRep.Label = &label
if value := userKc.GetAttributeString(constants.AttrbLabel); value != nil {
userRep.Label = value
}

if m["gender"] != nil {
var gender = m["gender"][0]
userRep.Gender = &gender
if value := userKc.GetAttributeString(constants.AttrbGender); value != nil {
userRep.Gender = value
}

if m["birthDate"] != nil {
var birthDate = m["birthDate"][0]
userRep.BirthDate = &birthDate
if value := userKc.GetAttributeDate(constants.AttrbBirthDate, constants.SupportedDateLayouts); value != nil {
userRep.BirthDate = value
}

if m["phoneNumberVerified"] != nil {
var phoneNumberVerified, _ = strconv.ParseBool(m["phoneNumberVerified"][0])
userRep.PhoneNumberVerified = &phoneNumberVerified
if value, err := userKc.GetAttributeBool(constants.AttrbPhoneNumberVerified); err == nil && value != nil {
userRep.PhoneNumberVerified = value
}

if m["locale"] != nil {
var locale = m["locale"][0]
userRep.Locale = &locale
if value := userKc.GetAttributeString(constants.AttrbLocale); value != nil {
userRep.Locale = value
}
if m["smsSent"] != nil {
var smsSent = m["smsSent"][0]
counter, _ := strconv.Atoi(smsSent)
userRep.SmsSent = &counter

if value, err := userKc.GetAttributeInt(constants.AttrbSmsSent); err == nil && value != nil {
userRep.SmsSent = value
}

if m["trustIDGroups"] != nil {
var trustIDGroups = m["trustIDGroups"]
userRep.TrustIDGroups = &trustIDGroups
if value := userKc.GetAttribute(constants.AttrbTrustIDGroups); value != nil {
userRep.TrustIDGroups = &value
}
}
return userRep
Expand Down
12 changes: 6 additions & 6 deletions api/management/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,32 +113,32 @@ func TestConvertToKCUser(t *testing.T) {
assert.Nil(t, ConvertToKCUser(user).Attributes)
var phoneNumber = "+4122555555"
user.PhoneNumber = &phoneNumber
assert.Equal(t, phoneNumber, (*ConvertToKCUser(user).Attributes)["phoneNumber"][0])
assert.Equal(t, phoneNumber, (*ConvertToKCUser(user).Attributes)[constants.AttrbPhoneNumber][0])

// Label
var label = "a label"
user.Label = &label
assert.Equal(t, label, (*ConvertToKCUser(user).Attributes)["label"][0])
assert.Equal(t, label, (*ConvertToKCUser(user).Attributes)[constants.AttrbLabel][0])

// Gender
var gender = "a gender"
user.Gender = &gender
assert.Equal(t, gender, (*ConvertToKCUser(user).Attributes)["gender"][0])
assert.Equal(t, gender, (*ConvertToKCUser(user).Attributes)[constants.AttrbGender][0])

// Birthdate
var date = "25/12/0"
user.BirthDate = &date
assert.Equal(t, date, (*ConvertToKCUser(user).Attributes)["birthDate"][0])
assert.Equal(t, date, (*ConvertToKCUser(user).Attributes)[constants.AttrbBirthDate][0])

// PhoneNumberVerified
var verified = true
user.PhoneNumberVerified = &verified
assert.Equal(t, "true", (*ConvertToKCUser(user).Attributes)["phoneNumberVerified"][0])
assert.Equal(t, "true", (*ConvertToKCUser(user).Attributes)[constants.AttrbPhoneNumberVerified][0])

// Locale
var locale = "it"
user.Locale = &locale
assert.Equal(t, locale, (*ConvertToKCUser(user).Attributes)["locale"][0])
assert.Equal(t, locale, (*ConvertToKCUser(user).Attributes)[constants.AttrbLocale][0])

}

Expand Down
12 changes: 6 additions & 6 deletions api/validation/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ func createValidKeycloakUser() kc.UserRepresentation {
lastName = "El-Bichoun"
email = "marcel.bichon@elca.ch"
attributes = kc.Attributes{
"gender": []string{"M"},
"phoneNumber": []string{"00 33 686 550011"},
"phoneNumberVerified": []string{"true"},
"birthDate": []string{"29.02.2020"},
constants.AttrbGender: []string{"M"},
constants.AttrbPhoneNumber: []string{"00 33 686 550011"},
constants.AttrbPhoneNumberVerified: []string{"true"},
constants.AttrbBirthDate: []string{"29.02.2020"},
}
)

Expand Down Expand Up @@ -132,9 +132,9 @@ func TestExportToKeycloak(t *testing.T) {
assert.Equal(t, user.FirstName, kcUser.FirstName)
assert.Equal(t, user.LastName, kcUser.LastName)
assert.Equal(t, user.EmailAddress, kcUser.Email)
assert.Equal(t, *user.PhoneNumber, (*kcUser.Attributes)["phoneNumber"][0])
assert.Equal(t, *user.PhoneNumber, *kcUser.GetAttributeString(constants.AttrbPhoneNumber))
assert.False(t, *kcUser.EmailVerified)
assert.Equal(t, "false", (*kcUser.Attributes)["phoneNumberVerified"][0])
assert.Equal(t, "false", *kcUser.GetAttributeString(constants.AttrbPhoneNumberVerified))
assert.True(t, *kcUser.Enabled)
})
}
Expand Down
5 changes: 3 additions & 2 deletions internal/constants/keycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ var (

// Attribute keys definition
const (
AttrbBirthDate = kc.AttributeKey("birthDate")
AttrbGender = kc.AttributeKey("gender")
AttrbBirthDate = kc.AttributeKey("ENC_birthDate")
AttrbGender = kc.AttributeKey("ENC_gender")
AttrbLabel = kc.AttributeKey("label")
AttrbLocale = kc.AttributeKey("locale")
AttrbPhoneNumber = kc.AttributeKey("phoneNumber")
AttrbPhoneNumberVerified = kc.AttributeKey("phoneNumberVerified")
AttrbSmsSent = kc.AttributeKey("smsSent")
AttrbTrustIDAuthToken = kc.AttributeKey("trustIDAuthToken")
AttrbTrustIDGroups = kc.AttributeKey("trustIDGroups")
)
30 changes: 30 additions & 0 deletions internal/keycloakb/pii.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package keycloakb

import (
"github.com/cloudtrust/keycloak-bridge/internal/constants"
"github.com/cloudtrust/keycloak-client"
kc "github.com/cloudtrust/keycloak-client"
)

var (
// These attributes should not be used anymore
attrbBirthDateLegacy = kc.AttributeKey("birthDate")
attrbGenderLegacy = kc.AttributeKey("gender")

piiAttributes = map[kc.AttributeKey]kc.AttributeKey{
constants.AttrbBirthDate: attrbBirthDateLegacy,
constants.AttrbGender: attrbGenderLegacy,
}
)

// CheckPII verify that PII are located in the well named attributes
func CheckPII(user *keycloak.UserRepresentation) {
for attrbSecure, attrbLegacy := range piiAttributes {
if value := user.GetAttributeString(attrbSecure); value == nil {
if value = user.GetAttributeString(attrbLegacy); value != nil {
user.SetAttributeString(attrbSecure, *value)
delete(*user.Attributes, attrbLegacy)
}
}
}
}
37 changes: 37 additions & 0 deletions internal/keycloakb/pii_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package keycloakb

import (
"testing"

"github.com/cloudtrust/keycloak-bridge/internal/constants"

kc "github.com/cloudtrust/keycloak-client"
"github.com/stretchr/testify/assert"
)

func TestCheckPII(t *testing.T) {
var kcUser kc.UserRepresentation

t.Run("No attributes", func(t *testing.T) {
CheckPII(&kcUser)
assert.Nil(t, kcUser.Attributes)
})
t.Run("One attribute without PII", func(t *testing.T) {
kcUser.SetAttributeString(kc.AttributeKey("non-pii"), "value")
CheckPII(&kcUser)
assert.Len(t, *kcUser.Attributes, 1)
})
t.Run("Two PII attributes in un-encrypted version", func(t *testing.T) {
var birthDate = "01.01.1999"
var gender = "M"
kcUser = kc.UserRepresentation{}
kcUser.SetAttributeString(attrbBirthDateLegacy, birthDate)
kcUser.SetAttributeString(attrbGenderLegacy, gender)
CheckPII(&kcUser)
assert.Len(t, *kcUser.Attributes, 2)
assert.Nil(t, kcUser.GetAttributeString(attrbBirthDateLegacy))
assert.Nil(t, kcUser.GetAttributeString(attrbGenderLegacy))
assert.Equal(t, birthDate, *kcUser.GetAttributeString(constants.AttrbBirthDate))
assert.Equal(t, gender, *kcUser.GetAttributeString(constants.AttrbGender))
})
}
5 changes: 3 additions & 2 deletions pkg/account/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func (c *component) GetAccount(ctx context.Context) (api.AccountRepresentation,
c.logger.Warn(ctx, "err", err.Error())
return userRep, err
}
keycloakb.CheckPII(&userKc)

var dbUser *dto.DBUser
dbUser, err = c.usersDBModule.GetUser(ctx, realm, userID)
Expand Down Expand Up @@ -157,6 +158,7 @@ func (c *component) UpdateAccount(ctx context.Context, user api.AccountRepresent
c.logger.Warn(ctx, "err", err.Error())
return err
}
keycloakb.CheckPII(&oldUserKc)

var emailVerified, phoneNumberVerified *bool
var actions []string
Expand All @@ -171,8 +173,7 @@ func (c *component) UpdateAccount(ctx context.Context, user api.AccountRepresent
// when the phone number changes, set the PhoneNumberVerified to false
if user.PhoneNumber != nil {
if oldUserKc.Attributes != nil {
var m = *oldUserKc.Attributes
if _, ok := m["phoneNumber"]; !ok || m["phoneNumber"][0] != *user.PhoneNumber {
if value := oldUserKc.GetAttributeString(constants.AttrbPhoneNumber); *value != *user.PhoneNumber {
var verified = false
phoneNumberVerified = &verified
actions = append(actions, ActionVerifyPhoneNumber)
Expand Down
Loading

0 comments on commit 8e2ce66

Please sign in to comment.