@@ -58,13 +58,12 @@ public async Task<string> GetLanguage()
58
58
{
59
59
string language = LanguageConst . Nb ;
60
60
61
- if ( this is not User and not SelfIdentifiedUser )
61
+ if ( this is not User )
62
62
return language ;
63
63
64
64
var profile = this switch
65
65
{
66
66
User user => await user . LookupProfile ( ) ,
67
- SelfIdentifiedUser selfIdentifiedUser => ( await selfIdentifiedUser . LoadDetails ( ) ) . Profile ,
68
67
_ => throw new InvalidOperationException ( $ "Unexpected case: { this . GetType ( ) . Name } ") ,
69
68
} ;
70
69
@@ -93,13 +92,23 @@ public sealed class User : Authenticated
93
92
/// </summary>
94
93
public int UserId { get ; }
95
94
95
+ /// <summary>
96
+ /// Username of the registered user, only relevant for self-identified/self-registered users.
97
+ /// E.g. BankID doesn't operate based on usernames, so this property would be null in that case.
98
+ /// </summary>
99
+ public string ? Username { get ; }
100
+
96
101
/// <summary>
97
102
/// Party ID
98
103
/// </summary>
99
104
public int UserPartyId { get ; }
100
105
101
106
/// <summary>
102
107
/// The party the user has selected through party selection
108
+ /// If the current request is related to an active instance, this value is not relevant.
109
+ /// The selected party ID is always whatever the user has selected in the party selection screen.
110
+ /// Party selection is used for instantiating new instances. The selected party ID becomes the instance owner party ID
111
+ /// when instantiating.
103
112
/// </summary>
104
113
public int SelectedPartyId { get ; }
105
114
@@ -118,6 +127,11 @@ public sealed class User : Authenticated
118
127
/// </summary>
119
128
public bool InAltinnPortal { get ; }
120
129
130
+ /// <summary>
131
+ /// True if the user is self-identified/self-registered.
132
+ /// </summary>
133
+ public bool IsSelfIdentified => AuthenticationLevel == 0 ;
134
+
121
135
private Details ? _extra ;
122
136
private readonly Func < int , Task < UserProfile ? > > _getUserProfile ;
123
137
private readonly Func < int , Task < Party ? > > _lookupParty ;
@@ -127,6 +141,7 @@ public sealed class User : Authenticated
127
141
128
142
internal User (
129
143
int userId ,
144
+ string ? username ,
130
145
int userPartyId ,
131
146
int authenticationLevel ,
132
147
string authenticationMethod ,
@@ -136,6 +151,7 @@ ref ParseContext context
136
151
: base ( ref context )
137
152
{
138
153
UserId = userId ;
154
+ Username = username ;
139
155
UserPartyId = userPartyId ;
140
156
SelectedPartyId = selectedPartyId ;
141
157
AuthenticationLevel = authenticationLevel ;
@@ -307,90 +323,6 @@ await _getUserProfile(UserId)
307
323
}
308
324
}
309
325
310
- /// <summary>
311
- /// The logged in client is a user (e.g. Altinn portal/ID-porten) with auth level 0.
312
- /// This means that the user has authenticated with a username/password, which can happen using
313
- /// * Altinn "self registered users"
314
- /// * ID-porten through Ansattporten ("low"), MinID self registered eID
315
- /// These have limited access to Altinn and can only represent themselves.
316
- /// </summary>
317
- public sealed class SelfIdentifiedUser : Authenticated
318
- {
319
- /// <summary>
320
- /// Username
321
- /// </summary>
322
- public string Username { get ; }
323
-
324
- /// <summary>
325
- /// User ID
326
- /// </summary>
327
- public int UserId { get ; }
328
-
329
- /// <summary>
330
- /// Party ID
331
- /// </summary>
332
- public int PartyId { get ; }
333
-
334
- /// <summary>
335
- /// Method of authentication, e.g. "idporten" or "maskinporten"
336
- /// </summary>
337
- public string AuthenticationMethod { get ; }
338
-
339
- private Details ? _extra ;
340
- private readonly Func < int , Task < UserProfile ? > > _getUserProfile ;
341
- private readonly ApplicationMetadata _appMetadata ;
342
-
343
- internal SelfIdentifiedUser (
344
- string username ,
345
- int userId ,
346
- int partyId ,
347
- string authenticationMethod ,
348
- ref ParseContext context
349
- )
350
- : base ( ref context )
351
- {
352
- Username = username ;
353
- UserId = userId ;
354
- PartyId = partyId ;
355
- AuthenticationMethod = authenticationMethod ;
356
- // Since they are self-identified, they are always 0
357
- AuthenticationLevel = 0 ;
358
- _getUserProfile = context . GetUserProfile ;
359
- _appMetadata = context . AppMetadata ;
360
- }
361
-
362
- /// <summary>
363
- /// Authentication level
364
- /// </summary>
365
- public int AuthenticationLevel { get ; }
366
-
367
- /// <summary>
368
- /// Detailed information about a logged in user
369
- /// </summary>
370
- public sealed record Details ( Party Party , UserProfile Profile , bool RepresentsSelf , bool CanInstantiate ) ;
371
-
372
- /// <summary>
373
- /// Load the details for the current user.
374
- /// </summary>
375
- /// <returns></returns>
376
- public async Task < Details > LoadDetails ( )
377
- {
378
- if ( _extra is not null )
379
- return _extra ;
380
-
381
- var userProfile =
382
- await _getUserProfile ( UserId )
383
- ?? throw new AuthenticationContextException (
384
- $ "Could not get user profile for logged in self identified user: { UserId } "
385
- ) ;
386
-
387
- var party = userProfile . Party ;
388
- var canInstantiate = InstantiationHelper . IsPartyAllowedToInstantiate ( party , _appMetadata . PartyTypesAllowed ) ;
389
- _extra = new Details ( party , userProfile , RepresentsSelf : true , canInstantiate ) ;
390
- return _extra ;
391
- }
392
- }
393
-
394
326
/// <summary>
395
327
/// The logged in client is an organisation (but they have not authenticated as an Altinn service owner).
396
328
/// Authentication has been done through Maskinporten.
@@ -690,13 +622,6 @@ internal static Authenticated FromLocalTest(
690
622
throw new AuthenticationContextException ( "Missing party ID for user token" ) ;
691
623
692
624
ParseAuthLevel ( context . AuthLevelClaim , out authLevel ) ;
693
- if ( authLevel == 0 )
694
- {
695
- if ( ! context . UsernameClaim . IsValidString ( out var usernameClaimValue ) )
696
- throw new AuthenticationContextException ( "Missing username claim for self-identified user token" ) ;
697
-
698
- return new SelfIdentifiedUser ( usernameClaimValue , userId , partyId . Value , "localtest" , ref context ) ;
699
- }
700
625
701
626
int selectedPartyId = partyId . Value ;
702
627
if ( getSelectedParty ( ) is { } selectedPartyStr )
@@ -706,8 +631,17 @@ internal static Authenticated FromLocalTest(
706
631
707
632
selectedPartyId = selectedParty ;
708
633
}
709
-
710
- return new User ( userId , partyId . Value , authLevel , "localtest" , selectedPartyId , ref context ) ;
634
+ context . UsernameClaim . IsValidString ( out var usernameClaimValue ) ;
635
+
636
+ return new User (
637
+ userId ,
638
+ usernameClaimValue ,
639
+ partyId . Value ,
640
+ authLevel ,
641
+ "localtest" ,
642
+ selectedPartyId ,
643
+ ref context
644
+ ) ;
711
645
}
712
646
713
647
internal record struct ParseContext (
@@ -936,7 +870,7 @@ internal static Authenticated From(
936
870
return NewUser ( ref context ) ;
937
871
}
938
872
939
- static Authenticated NewUser ( ref ParseContext context )
873
+ static Authenticated . User NewUser ( ref ParseContext context )
940
874
{
941
875
if ( ! context . UserIdClaim . Exists )
942
876
throw new AuthenticationContextException ( "Missing user ID claim for user token" ) ;
@@ -959,19 +893,6 @@ static Authenticated NewUser(ref ParseContext context)
959
893
throw new AuthenticationContextException ( "Missing or invalid authentication method claim for user token" ) ;
960
894
961
895
ParseAuthLevel ( context . AuthLevelClaim , out var authLevel ) ;
962
- if ( authLevel == 0 )
963
- {
964
- if ( ! context . UsernameClaim . IsValidString ( out var usernameClaimValue ) )
965
- throw new AuthenticationContextException ( "Missing username claim for self-identified user token" ) ;
966
-
967
- return new SelfIdentifiedUser (
968
- usernameClaimValue ,
969
- userId . Value ,
970
- partyId . Value ,
971
- authMethodClaimValue ,
972
- ref context
973
- ) ;
974
- }
975
896
976
897
int selectedPartyId = partyId . Value ;
977
898
if ( context . GetSelectedParty ( ) is { } selectedPartyStr )
@@ -982,7 +903,17 @@ ref context
982
903
selectedPartyId = selectedParty ;
983
904
}
984
905
985
- return new User ( userId . Value , partyId . Value , authLevel , authMethodClaimValue , selectedPartyId , ref context ) ;
906
+ context . UsernameClaim . IsValidString ( out var usernameClaimValue ) ;
907
+
908
+ return new User (
909
+ userId . Value ,
910
+ usernameClaimValue ,
911
+ partyId . Value ,
912
+ authLevel ,
913
+ authMethodClaimValue ,
914
+ selectedPartyId ,
915
+ ref context
916
+ ) ;
986
917
}
987
918
988
919
static Org NewOrg ( ref ParseContext context )
0 commit comments