mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-22 16:13:31 +01:00
Specify invited by email when inviting a user (#1087)
This commit is contained in:
parent
4572c6c1f8
commit
8e3bcd57a2
@ -461,7 +461,7 @@ func (am *Auth0Manager) UpdateUserAppMetadata(userID string, appMetadata AppMeta
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildCreateUserRequestPayload(email string, name string, accountID string) (string, error) {
|
func buildCreateUserRequestPayload(email, name, accountID, invitedByEmail string) (string, error) {
|
||||||
invite := true
|
invite := true
|
||||||
req := &createUserRequest{
|
req := &createUserRequest{
|
||||||
Email: email,
|
Email: email,
|
||||||
@ -469,6 +469,7 @@ func buildCreateUserRequestPayload(email string, name string, accountID string)
|
|||||||
AppMeta: AppMetadata{
|
AppMeta: AppMetadata{
|
||||||
WTAccountID: accountID,
|
WTAccountID: accountID,
|
||||||
WTPendingInvite: &invite,
|
WTPendingInvite: &invite,
|
||||||
|
WTInvitedBy: invitedByEmail,
|
||||||
},
|
},
|
||||||
Connection: "Username-Password-Authentication",
|
Connection: "Username-Password-Authentication",
|
||||||
Password: GeneratePassword(8, 1, 1, 1),
|
Password: GeneratePassword(8, 1, 1, 1),
|
||||||
@ -634,9 +635,9 @@ func (am *Auth0Manager) GetUserByEmail(email string) ([]*UserData, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in Auth0 Idp and sends an invite
|
// CreateUser creates a new user in Auth0 Idp and sends an invite
|
||||||
func (am *Auth0Manager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (am *Auth0Manager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
|
|
||||||
payloadString, err := buildCreateUserRequestPayload(email, name, accountID)
|
payloadString, err := buildCreateUserRequestPayload(email, name, accountID, invitedByEmail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ func TestAuth0_UpdateUserAppMetadata(t *testing.T) {
|
|||||||
updateUserAppMetadataTestCase2 := updateUserAppMetadataTest{
|
updateUserAppMetadataTestCase2 := updateUserAppMetadataTest{
|
||||||
name: "Bad Status Code",
|
name: "Bad Status Code",
|
||||||
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
||||||
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":null}}", appMetadata.WTAccountID),
|
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":null,\"wt_invited_by_email\":\"\"}}", appMetadata.WTAccountID),
|
||||||
appMetadata: appMetadata,
|
appMetadata: appMetadata,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
helper: JsonParser{},
|
helper: JsonParser{},
|
||||||
@ -366,7 +366,7 @@ func TestAuth0_UpdateUserAppMetadata(t *testing.T) {
|
|||||||
updateUserAppMetadataTestCase4 := updateUserAppMetadataTest{
|
updateUserAppMetadataTestCase4 := updateUserAppMetadataTest{
|
||||||
name: "Good request",
|
name: "Good request",
|
||||||
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
||||||
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":null}}", appMetadata.WTAccountID),
|
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":null,\"wt_invited_by_email\":\"\"}}", appMetadata.WTAccountID),
|
||||||
appMetadata: appMetadata,
|
appMetadata: appMetadata,
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
helper: JsonParser{},
|
helper: JsonParser{},
|
||||||
@ -378,7 +378,7 @@ func TestAuth0_UpdateUserAppMetadata(t *testing.T) {
|
|||||||
updateUserAppMetadataTestCase5 := updateUserAppMetadataTest{
|
updateUserAppMetadataTestCase5 := updateUserAppMetadataTest{
|
||||||
name: "Update Pending Invite",
|
name: "Update Pending Invite",
|
||||||
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
inputReqBody: fmt.Sprintf("{\"access_token\":\"%s\",\"scope\":\"read:users\",\"expires_in\":%d,\"token_type\":\"Bearer\"}", token, exp),
|
||||||
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":true}}", appMetadata.WTAccountID),
|
expectedReqBody: fmt.Sprintf("{\"app_metadata\":{\"wt_account_id\":\"%s\",\"wt_pending_invite\":true,\"wt_invited_by_email\":\"\"}}", appMetadata.WTAccountID),
|
||||||
appMetadata: AppMetadata{
|
appMetadata: AppMetadata{
|
||||||
WTAccountID: "ok",
|
WTAccountID: "ok",
|
||||||
WTPendingInvite: &invite,
|
WTPendingInvite: &invite,
|
||||||
|
@ -362,7 +362,7 @@ func (am *AuthentikManager) GetAllAccounts() (map[string][]*UserData, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in authentik Idp and sends an invitation.
|
// CreateUser creates a new user in authentik Idp and sends an invitation.
|
||||||
func (am *AuthentikManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (am *AuthentikManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
ctx, err := am.authenticationContext()
|
ctx, err := am.authenticationContext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -236,7 +236,7 @@ func (ac *AzureCredentials) Authenticate() (JWTToken, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in azure AD Idp.
|
// CreateUser creates a new user in azure AD Idp.
|
||||||
func (am *AzureManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (am *AzureManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
payload, err := buildAzureCreateUserRequestPayload(email, name, accountID, am.ClientID)
|
payload, err := buildAzureCreateUserRequestPayload(email, name, accountID, am.ClientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -185,7 +185,7 @@ func (gm *GoogleWorkspaceManager) GetAllAccounts() (map[string][]*UserData, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in Google Workspace and sends an invitation.
|
// CreateUser creates a new user in Google Workspace and sends an invitation.
|
||||||
func (gm *GoogleWorkspaceManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (gm *GoogleWorkspaceManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
invite := true
|
invite := true
|
||||||
metadata := AppMetadata{
|
metadata := AppMetadata{
|
||||||
WTAccountID: accountID,
|
WTAccountID: accountID,
|
||||||
|
@ -15,7 +15,7 @@ type Manager interface {
|
|||||||
GetUserDataByID(userId string, appMetadata AppMetadata) (*UserData, error)
|
GetUserDataByID(userId string, appMetadata AppMetadata) (*UserData, error)
|
||||||
GetAccount(accountId string) ([]*UserData, error)
|
GetAccount(accountId string) ([]*UserData, error)
|
||||||
GetAllAccounts() (map[string][]*UserData, error)
|
GetAllAccounts() (map[string][]*UserData, error)
|
||||||
CreateUser(email string, name string, accountID string) (*UserData, error)
|
CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error)
|
||||||
GetUserByEmail(email string) ([]*UserData, error)
|
GetUserByEmail(email string) ([]*UserData, error)
|
||||||
InviteUserByID(userID string) error
|
InviteUserByID(userID string) error
|
||||||
}
|
}
|
||||||
@ -72,6 +72,7 @@ type AppMetadata struct {
|
|||||||
// maps to wt_account_id when json.marshal
|
// maps to wt_account_id when json.marshal
|
||||||
WTAccountID string `json:"wt_account_id,omitempty"`
|
WTAccountID string `json:"wt_account_id,omitempty"`
|
||||||
WTPendingInvite *bool `json:"wt_pending_invite"`
|
WTPendingInvite *bool `json:"wt_pending_invite"`
|
||||||
|
WTInvitedBy string `json:"wt_invited_by_email"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTToken a JWT object that holds information of a token
|
// JWTToken a JWT object that holds information of a token
|
||||||
|
@ -230,7 +230,7 @@ func (kc *KeycloakCredentials) Authenticate() (JWTToken, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in keycloak Idp and sends an invite.
|
// CreateUser creates a new user in keycloak Idp and sends an invite.
|
||||||
func (km *KeycloakManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (km *KeycloakManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
jwtToken, err := km.credentials.Authenticate()
|
jwtToken, err := km.credentials.Authenticate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -103,7 +103,7 @@ func (oc *OktaCredentials) Authenticate() (JWTToken, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in okta Idp and sends an invitation.
|
// CreateUser creates a new user in okta Idp and sends an invitation.
|
||||||
func (om *OktaManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (om *OktaManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
var (
|
var (
|
||||||
sendEmail = true
|
sendEmail = true
|
||||||
activate = true
|
activate = true
|
||||||
|
@ -234,7 +234,7 @@ func (zc *ZitadelCredentials) Authenticate() (JWTToken, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates a new user in zitadel Idp and sends an invite.
|
// CreateUser creates a new user in zitadel Idp and sends an invite.
|
||||||
func (zm *ZitadelManager) CreateUser(email string, name string, accountID string) (*UserData, error) {
|
func (zm *ZitadelManager) CreateUser(email, name, accountID, invitedByEmail string) (*UserData, error) {
|
||||||
payload, err := buildZitadelCreateUserRequestPayload(email, name)
|
payload, err := buildZitadelCreateUserRequestPayload(email, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -215,6 +215,12 @@ func (am *DefaultAccountManager) inviteNewUser(accountID, userID string, invite
|
|||||||
return nil, status.Errorf(status.NotFound, "account %s doesn't exist", accountID)
|
return nil, status.Errorf(status.NotFound, "account %s doesn't exist", accountID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initiator is the one who is inviting the new user
|
||||||
|
initiatorUser, err := am.lookupUserInCache(userID, account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(status.NotFound, "user %s doesn't exist in IdP", userID)
|
||||||
|
}
|
||||||
|
|
||||||
// check if the user is already registered with this email => reject
|
// check if the user is already registered with this email => reject
|
||||||
user, err := am.lookupUserInCacheByEmail(invite.Email, accountID)
|
user, err := am.lookupUserInCacheByEmail(invite.Email, accountID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -234,7 +240,7 @@ func (am *DefaultAccountManager) inviteNewUser(accountID, userID string, invite
|
|||||||
return nil, status.Errorf(status.UserAlreadyExists, "can't invite a user with an existing NetBird account")
|
return nil, status.Errorf(status.UserAlreadyExists, "can't invite a user with an existing NetBird account")
|
||||||
}
|
}
|
||||||
|
|
||||||
idpUser, err := am.idpManager.CreateUser(invite.Email, invite.Name, accountID)
|
idpUser, err := am.idpManager.CreateUser(invite.Email, invite.Name, accountID, initiatorUser.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user