Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion cmd/devinit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ func createIdentityProviders(factory store.Factory, err error, orgId string, env
if err != nil {
return err
}

idp := &types.IdentityProvider{
Name: "Fake OIDC",
OrganizationID: orgId,
Expand All @@ -330,7 +331,13 @@ func createIdentityProviders(factory store.Factory, err error, orgId string, env
ClientSecret: envCfg.idpClientSecret,
EmailDomain: "nrc.no",
Scopes: "openid profile offline_access",
ClaimMappings: types.ClaimMappings{Mappings: nil, Version: "0"},
ClaimMappings: types.ClaimMappings{
Subject: "{{.sub}}",
DisplayName: "{{.displayName}}",
FullName: "{{.fullName}}",
Email: "{{.email}}",
EmailVerified: "{{.emailVerified}}",
Version: "0"},
}
if len(idps) == 0 {
_, err := idpStore.Create(context.Background(), idp, store.IdentityProviderCreateOptions{})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Clients } from './clients/Clients';

const AuthenticatedApp: FC = () => {
return (
<div className="d-flex flex-column vh-100 vw-100 bg-dark">
<div className="d-flex flex-column min-vh-100 vw-100 bg-dark">
<NavBar />
<Switch>
<Route path="/organizations/add" component={OrganizationEditor} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ type FormData = {
organizationId: string;
emailDomain: string;
scopes: string;
claimMappings: { Version: string; Mappings: any };
claimMappings: {
version: string;
subject: string;
displayName: string;
fullName: string;
email: string;
emailVerified: string;
};
};

export const IdentityProviderEditor: FC<Props> = (props) => {
Expand Down Expand Up @@ -49,18 +56,18 @@ export const IdentityProviderEditor: FC<Props> = (props) => {
setValue('emailDomain', data.emailDomain);
setValue('clientSecret', '');
setValue('scopes', data.scopes);
setValue(
'claimMappings.Mappings',
JSON.stringify(data.claimMappings.Mappings),
);
setVersion(data.claimMappings.Version);
setValue('claimMappings.subject', data.claimMappings.subject);
setValue('claimMappings.displayName', data.claimMappings.displayName);
setValue('claimMappings.fullName', data.claimMappings.fullName);
setValue('claimMappings.email', data.claimMappings.email);
setValue('claimMappings.emailVerified', data.claimMappings.emailVerified);
setVersion(data.claimMappings.version);
};

useEffect(() => {
if (id) {
apiClient.getIdentityProvider({ id }).then((resp) => {
if (resp.response) {
console.log('RESP', resp.response);
setData(resp.response);
}
});
Expand All @@ -81,8 +88,12 @@ export const IdentityProviderEditor: FC<Props> = (props) => {
emailDomain: args.emailDomain,
scopes: args.scopes,
claimMappings: {
Version: newVersion,
Mappings: JSON.parse(args.claimMappings.Mappings),
version: newVersion,
subject: args.claimMappings.subject,
displayName: args.claimMappings.displayName,
fullName: args.claimMappings.fullName,
email: args.claimMappings.email,
emailVerified: args.claimMappings.emailVerified,
},
};
let resp;
Expand Down Expand Up @@ -192,20 +203,110 @@ export const IdentityProviderEditor: FC<Props> = (props) => {
{fieldErrors('scopes')}
</div>

<div className="form-group mb-2">
<label className="form-label text-light">
Claim Mapping (Version: {version})
</label>
<textarea
{...register('claimMappings.Mappings', {
required: true,
})}
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.Mappings'),
)}
/>
<h6 className="text-light mt-5">
Claim Mapping, Current Version: {version}
</h6>
<p className="form-text text-muted mb-4">
Please use go template syntax:
<a
href="https://blog.gopheracademy.com/advent-2017/using-go-templates/"
target="_blank"
rel="noreferrer"
>
Examples
</a>
</p>

<div className="form-group row mb-3">
<div className="col-sm-2 text-light">
<label htmlFor="subject">Subject</label>
</div>
<div className="col-sm-10">
<input
{...register('claimMappings.subject', {
required: true,
})}
id="subject"
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.subject'),
)}
/>
</div>
</div>

<div className="form-group row mb-3">
<div className="col-sm-2 text-light">
<label htmlFor="displayName">Display Name</label>
</div>
<div className="col-sm-10">
<input
{...register('claimMappings.displayName', {
required: true,
})}
id="displayName"
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.displayName'),
)}
/>
</div>
</div>

<div className="form-group row mb-3">
<div className="col-sm-2 text-light">
<label htmlFor="fullName">Full Name</label>
</div>
<div className="col-sm-10">
<input
{...register('claimMappings.fullName', {
required: true,
})}
id="fullName"
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.fullName'),
)}
/>
</div>
</div>

<div className="form-group row mb-3">
<div className="col-sm-2 text-light">
<label htmlFor="email">Email</label>
</div>
<div className="col-sm-10">
<input
{...register('claimMappings.email', {
required: true,
})}
id="email"
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.email'),
)}
/>
</div>
</div>

<div className="form-group row mb-3">
<div className="col-sm-2 text-light">
<label htmlFor="emailVerified">Email Verified</label>
</div>
<div className="col-sm-10">
<input
{...register('claimMappings.emailVerified', {
required: true,
})}
id="emailVerified"
className={classNames(
'form-control form-control-darkula',
fieldClasses('claimMappings.emailVerified'),
)}
/>
</div>
</div>

{fieldErrors('claimMappings')}

<button disabled={isSubmitting} className="btn btn-success mt-2">
Expand Down
8 changes: 6 additions & 2 deletions frontend/apps/core-authnz-frontend/src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,12 @@ export class IdentityProvider {
public scopes = '';

public claimMappings = {
Version: '0',
Mappings: {},
version: '0',
subject: '',
displayName: '',
fullName: '',
email: '',
emailVerified: '',
};
}

Expand Down
9 changes: 7 additions & 2 deletions pkg/api/types/identity_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ type IdentityProvider struct {
}

type ClaimMappings struct {
Version string `json:"Version"`
Mappings map[string]string `json:"Mappings"`
Version string `json:"version"`
Subject string `json:"subject"`
DisplayName string `json:"displayName"`
FullName string `json:"fullName"`
Email string `json:"email"`
EmailVerified string `json:"emailVerified"`
}


// IdentityProviderList represents a list of IdentityProvider
type IdentityProviderList struct {
Items []*IdentityProvider `json:"items"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ func handleAuthCodeExchangeSucceeded(
}

l.Debug("finding user identifier for oidc provider", zap.String("subject", authRequest.Claims.Subject), zap.String("domain", idp.Domain))
identifier, err := loginStore.FindOidcIdentifier(authRequest.Claims.Subject, idp.Domain)
identifier, err := loginStore.FindOidcIdentifier(ctx, authRequest.Claims.Subject, idp.Domain)
if err != nil {
if meta.ReasonForError(err) == meta.StatusReasonNotFound {
l.Info("user identifier not found. creating new identity")
newIdentity, err := loginStore.CreateOidcIdentity(
ctx,
idp.Domain,
authRequest.Claims.Subject,
authRequest.AccessToken,
Expand All @@ -45,6 +46,22 @@ func handleAuthCodeExchangeSucceeded(
return err
}
identifier = newIdentity.Credentials[0].Identifiers[0]

newIdentityProfile := store2.IdentityProfile{
ID: newIdentity.ID,
IdentityProviderID: idp.ID,
Subject: authRequest.Claims.Subject,
DisplayName: authRequest.Claims.DisplayName,
FullName: authRequest.Claims.FullName,
Email: authRequest.Claims.Email,
EmailVerified: authRequest.Claims.EmailVerified,
}

if err := loginStore.CreateOidcIdentityProfile(ctx, newIdentityProfile); err != nil {
l.Error("failed to store identity profile", zap.Error(err))
return err
}

} else {
l.Error("failed to get user identifier for oidc provider", zap.Error(err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this intended?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like I had a reason but I cannot remember it for the life of me, so let's say no 😅

return err
Expand Down
Loading