Skip to content

Commit

Permalink
Merge b3962bb into e6e3484
Browse files Browse the repository at this point in the history
  • Loading branch information
fperot74 committed Mar 11, 2020
2 parents e6e3484 + b3962bb commit 61faac8
Show file tree
Hide file tree
Showing 25 changed files with 760 additions and 235 deletions.
55 changes: 38 additions & 17 deletions api/account/api.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
package account

import (
"encoding/json"

"github.com/cloudtrust/common-service/validation"
"github.com/cloudtrust/keycloak-bridge/internal/constants"
msg "github.com/cloudtrust/keycloak-bridge/internal/constants"
"github.com/cloudtrust/keycloak-bridge/internal/keycloakb"
kc "github.com/cloudtrust/keycloak-client"
)

// AccountRepresentation struct
type AccountRepresentation struct {
Username *string `json:"username,omitempty"`
Email *string `json:"email,omitempty"`
EmailVerified *bool `json:"emailVerified,omitempty"`
Gender *string `json:"gender,omitempty"`
FirstName *string `json:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty"`
PhoneNumber *string `json:"phoneNumber,omitempty"`
PhoneNumberVerified *bool `json:"phoneNumberVerified,omitempty"`
BirthDate *string `json:"birthDate,omitempty"`
BirthLocation *string `json:"birthLocation,omitempty"`
IDDocumentType *string `json:"idDocumentType,omitempty"`
IDDocumentNumber *string `json:"idDocumentNumber,omitempty"`
IDDocumentExpiration *string `json:"idDocumentExpiration,omitempty"`
Locale *string `json:"locale,omitempty"`
Username *string `json:"username,omitempty"`
Email *string `json:"email,omitempty"`
EmailVerified *bool `json:"emailVerified,omitempty"`
Gender *string `json:"gender,omitempty"`
FirstName *string `json:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty"`
PhoneNumber *string `json:"phoneNumber,omitempty"`
PhoneNumberVerified *bool `json:"phoneNumberVerified,omitempty"`
BirthDate *string `json:"birthDate,omitempty"`
BirthLocation *string `json:"birthLocation,omitempty"`
IDDocumentType *string `json:"idDocumentType,omitempty"`
IDDocumentNumber *string `json:"idDocumentNumber,omitempty"`
IDDocumentExpiration *string `json:"idDocumentExpiration,omitempty"`
Locale *string `json:"locale,omitempty"`
Accreditations *[]AccreditationRepresentation `json:"accreditations,omitempty"`
}

// AccreditationRepresentation is a representation of accreditations
type AccreditationRepresentation struct {
Type *string `json:"type"`
ExpiryDate *string `json:"expiryDate"`
Expired *bool `json:"expired,omitempty"`
}

// CredentialRepresentation struct
Expand Down Expand Up @@ -72,7 +83,7 @@ func ConvertCredential(credKc *kc.CredentialRepresentation) CredentialRepresenta
return cred
}

// ConvertToAPIAccount creates an API account representation from a KC user representation
// ConvertToAPIAccount creates an API account representation from a KC user representation
func ConvertToAPIAccount(userKc kc.UserRepresentation) AccountRepresentation {
var userRep AccountRepresentation

Expand All @@ -85,6 +96,9 @@ func ConvertToAPIAccount(userKc kc.UserRepresentation) AccountRepresentation {
if value := userKc.GetAttributeString(constants.AttrbPhoneNumber); value != nil {
userRep.PhoneNumber = value
}
if verified, err := userKc.GetAttributeBool(constants.AttrbPhoneNumberVerified); err == nil && verified != nil {
userRep.PhoneNumberVerified = verified
}
if value := userKc.GetAttributeString(constants.AttrbGender); value != nil {
userRep.Gender = value
}
Expand All @@ -94,8 +108,15 @@ func ConvertToAPIAccount(userKc kc.UserRepresentation) AccountRepresentation {
if value := userKc.GetAttributeString(constants.AttrbLocale); value != nil {
userRep.Locale = value
}
if verified, err := userKc.GetAttributeBool(constants.AttrbPhoneNumberVerified); err == nil && verified != nil {
userRep.PhoneNumberVerified = verified
if values := userKc.GetAttribute(constants.AttrbAccreditations); len(values) > 0 {
var accreds []AccreditationRepresentation
for _, accredJSON := range values {
var accred AccreditationRepresentation
json.Unmarshal([]byte(accredJSON), &accred)
accred.Expired = keycloakb.IsDateInThePast(accred.ExpiryDate)
accreds = append(accreds, accred)
}
userRep.Accreditations = &accreds
}

return userRep
Expand Down
2 changes: 2 additions & 0 deletions api/account/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func TestConvertToAPIAccount(t *testing.T) {
"birthDate": []string{"15.02.1920"},
"locale": []string{"fr"},
"phoneNumberVerified": []string{"true"},
"accreditations": []string{`{"type":"one","expiryDate":"05.04.2020"}`, `{"type":"two","expiryDate":"05.03.2022"}`},
}

t.Run("Check attributes are copied", func(t *testing.T) {
Expand All @@ -54,6 +55,7 @@ func TestConvertToAPIAccount(t *testing.T) {
assert.Equal(t, "15.02.1920", *user.BirthDate)
assert.Equal(t, "fr", *user.Locale)
assert.True(t, *user.PhoneNumberVerified)
assert.Len(t, *user.Accreditations, 2)
})

t.Run("PhoneNumberVerified is invalid", func(t *testing.T) {
Expand Down
15 changes: 15 additions & 0 deletions api/account/swagger-api_account.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,21 @@ components:
description: only returned by /account
locale:
type: string
accreditations:
type: array
description: only returned by /account
items:
type: object
properties:
type:
type: string
description: accreditation type
expiryDate:
type: string
description: expiry date. format is DD.MM.YYYY
expired:
type: bool
description: true if the expiry date has passed
Configuration:
type: object
properties:
Expand Down
77 changes: 46 additions & 31 deletions api/kyc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package apikyc

import (
"encoding/json"
"strconv"
"strings"

"github.com/cloudtrust/common-service/validation"
"github.com/cloudtrust/keycloak-bridge/internal/constants"
"github.com/cloudtrust/keycloak-bridge/internal/keycloakb"
kc "github.com/cloudtrust/keycloak-client"
)

Expand All @@ -18,21 +18,29 @@ type ActionRepresentation struct {

// UserRepresentation contains user details
type UserRepresentation struct {
UserID *string `json:"userId,omitempty"`
Username *string `json:"username,omitempty"`
Gender *string `json:"gender,omitempty"`
FirstName *string `json:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty"`
EmailAddress *string `json:"emailAddress,omitempty"`
EmailAddressVerified *bool `json:"emailAddressVerified,omitempty"`
PhoneNumber *string `json:"phoneNumber,omitempty"`
PhoneNumberVerified *bool `json:"phoneNumberVerified,omitempty"`
BirthDate *string `json:"birthDate,omitempty"`
BirthLocation *string `json:"birthLocation,omitempty"`
IDDocumentType *string `json:"idDocumentType,omitempty"`
IDDocumentNumber *string `json:"idDocumentNumber,omitempty"`
IDDocumentExpiration *string `json:"idDocumentExpiration,omitempty"`
Comment *string `json:"comment,omitempty"`
UserID *string `json:"userId,omitempty"`
Username *string `json:"username,omitempty"`
Gender *string `json:"gender,omitempty"`
FirstName *string `json:"firstName,omitempty"`
LastName *string `json:"lastName,omitempty"`
EmailAddress *string `json:"emailAddress,omitempty"`
EmailAddressVerified *bool `json:"emailAddressVerified,omitempty"`
PhoneNumber *string `json:"phoneNumber,omitempty"`
PhoneNumberVerified *bool `json:"phoneNumberVerified,omitempty"`
BirthDate *string `json:"birthDate,omitempty"`
BirthLocation *string `json:"birthLocation,omitempty"`
IDDocumentType *string `json:"idDocumentType,omitempty"`
IDDocumentNumber *string `json:"idDocumentNumber,omitempty"`
IDDocumentExpiration *string `json:"idDocumentExpiration,omitempty"`
Comment *string `json:"comment,omitempty"`
Accreditations *[]AccreditationRepresentation `json:"accreditations,omitempty"`
}

// AccreditationRepresentation is a representation of accreditations
type AccreditationRepresentation struct {
Type *string `json:"type"`
ExpiryDate *string `json:"expiryDate"`
Expired *bool `json:"expired,omitempty"`
}

// Parameter references
Expand Down Expand Up @@ -121,23 +129,29 @@ func (u *UserRepresentation) ImportFromKeycloak(kcUser *kc.UserRepresentation) {
var phoneNumberVerified = u.PhoneNumberVerified
var gender = u.Gender
var birthdate = u.BirthDate
var accreditations = u.Accreditations

if kcUser.Attributes != nil {
var m = *kcUser.Attributes
if value, ok := m["phoneNumber"]; ok && len(value) > 0 {
phoneNumber = &value[0]
}
if value, ok := m["phoneNumberVerified"]; ok && len(value) > 0 {
if verified, err := strconv.ParseBool(value[0]); err == nil {
phoneNumberVerified = &verified
}
}
if value, ok := m["gender"]; ok && len(value) > 0 {
gender = &value[0]
}
if value, ok := m["birthDate"]; ok && len(value) > 0 {
birthdate = &value[0]
if value := kcUser.GetAttributeString(constants.AttrbPhoneNumber); value != nil {
phoneNumber = value
}
if value, err := kcUser.GetAttributeBool(constants.AttrbPhoneNumberVerified); err == nil && value != nil {
phoneNumberVerified = value
}
if value := kcUser.GetAttributeString(constants.AttrbGender); value != nil {
gender = value
}
if value := kcUser.GetAttributeDate(constants.AttrbBirthDate, constants.SupportedDateLayouts); value != nil {
birthdate = value
}
if values := kcUser.GetAttribute(constants.AttrbAccreditations); len(values) > 0 {
var accreds []AccreditationRepresentation
for _, accredJSON := range values {
var accred AccreditationRepresentation
json.Unmarshal([]byte(accredJSON), &accred)
accred.Expired = keycloakb.IsDateInThePast(accred.ExpiryDate)
accreds = append(accreds, accred)
}
accreditations = &accreds
}

u.UserID = kcUser.Id
Expand All @@ -150,6 +164,7 @@ func (u *UserRepresentation) ImportFromKeycloak(kcUser *kc.UserRepresentation) {
u.PhoneNumber = phoneNumber
u.PhoneNumberVerified = phoneNumberVerified
u.BirthDate = birthdate
u.Accreditations = accreditations
}

// Validate checks the validity of the given User
Expand Down
27 changes: 18 additions & 9 deletions api/kyc/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ package apikyc
import (
"testing"

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

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

func ptr(value string) *string {
return &value
}

func createValidUser() UserRepresentation {
var (
bFalse = false
Expand All @@ -21,6 +27,9 @@ func createValidUser() UserRepresentation {
idDocType = "PASSPORT"
idDocNumber = "123456789"
idDocExpiration = "23.02.2039"
accred1 = AccreditationRepresentation{Type: ptr("short"), ExpiryDate: ptr("31.12.2024")}
accred2 = AccreditationRepresentation{Type: ptr("long"), ExpiryDate: ptr("31.12.2039")}
creds = []AccreditationRepresentation{accred1, accred2}
)

return UserRepresentation{
Expand All @@ -37,6 +46,7 @@ func createValidUser() UserRepresentation {
IDDocumentType: &idDocType,
IDDocumentNumber: &idDocNumber,
IDDocumentExpiration: &idDocExpiration,
Accreditations: &creds,
}
}

Expand All @@ -51,6 +61,7 @@ func createValidKeycloakUser() kc.UserRepresentation {
"phoneNumber": []string{"00 33 686 550011"},
"phoneNumberVerified": []string{"true"},
"birthDate": []string{"29.02.2020"},
"accreditations": []string{`{"type":"one","expiryDate":"05.04.2020"}`, `{"type":"two","expiryDate":"05.03.2022"}`},
}
)

Expand Down Expand Up @@ -127,19 +138,17 @@ func TestExportToKeycloak(t *testing.T) {
}

func TestImportFromKeycloak(t *testing.T) {
var user = createValidUser()
user.BirthLocation = nil
user.IDDocumentType = nil
user.IDDocumentNumber = nil
user.IDDocumentExpiration = nil

var kcUser kc.UserRepresentation
user.ExportToKeycloak(&kcUser)
var kcUser = createValidKeycloakUser()
kcUser.SetAttributeBool(constants.AttrbPhoneNumberVerified, true)

var imported = UserRepresentation{}
imported.ImportFromKeycloak(&kcUser)

assert.Equal(t, user, imported)
assert.Equal(t, *kcUser.FirstName, *imported.FirstName)
assert.Equal(t, *kcUser.LastName, *imported.LastName)
assert.Equal(t, *kcUser.GetAttributeString(constants.AttrbGender), *imported.Gender)
assert.Len(t, kcUser.GetAttribute(constants.AttrbAccreditations), 2)
assert.True(t, *imported.PhoneNumberVerified)
}

func TestValidateUserRepresentation(t *testing.T) {
Expand Down
15 changes: 15 additions & 0 deletions api/kyc/swagger-api_kyc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,21 @@ components:
validation:
type: string
description: Only provided by getUser
accreditations:
type: array
description: Used only by getUser
items:
type: object
properties:
type:
type: string
description: accreditation type
expiryDate:
type: string
description: expiry date. format is DD.MM.YYYY
expired:
type: bool
description: true if the expiry date has passed
securitySchemes:
openId:
type: openIdConnect
Expand Down
Loading

0 comments on commit 61faac8

Please sign in to comment.