11using System . ComponentModel . DataAnnotations ;
22using System . Net . Mime ;
3+ using System . Security . Claims ;
34using Altinn . AccessManagement . Api . Enduser . Models ;
45using Altinn . AccessManagement . Core . Constants ;
56using Altinn . AccessManagement . Core . Errors ;
1213using Altinn . AccessMgmt . PersistenceEF . Constants ;
1314using Altinn . AccessMgmt . PersistenceEF . Queries . Connection ;
1415using Altinn . AccessMgmt . PersistenceEF . Utils ;
16+ using Altinn . Authorization . ABAC . Xacml . JsonProfile ;
1517using Altinn . Authorization . Api . Contracts . AccessManagement ;
1618using Altinn . Authorization . Api . Contracts . AccessManagement . Request ;
1719using Altinn . Authorization . ProblemDetails ;
20+ using Altinn . Common . PEP . Helpers ;
21+ using Altinn . Common . PEP . Interfaces ;
1822using Azure . Core ;
1923using Microsoft . AspNetCore . Authorization ;
2024using Microsoft . AspNetCore . Mvc ;
@@ -32,7 +36,8 @@ public class RequestController(
3236 IConnectionService connectionService ,
3337 ConnectionQuery connectionQuery ,
3438 IResourceService resourceService ,
35- IEntityService entityService
39+ IEntityService entityService ,
40+ IPDP Pdp
3641 ) : ControllerBase
3742{
3843 private Action < ConnectionOptions > ConfigureConnections { get ; } = options =>
@@ -96,6 +101,35 @@ public async Task<IActionResult> GetReceivedRequests(
96101 return result . IsSuccess ? Ok ( PaginatedResult . Create ( result . Value , null ) ) : result . Problem . ToActionResult ( ) ;
97102 }
98103
104+ [ HttpGet ( "draft" ) ]
105+ [ FeatureGate ( RequirementType . Any , AccessMgmtFeatureFlags . EnableRequestAssignmentResource ) ]
106+ [ Authorize ( Policy = AuthzConstants . SCOPE_PORTAL_ENDUSER ) ]
107+ [ ProducesResponseType < RequestDto > ( StatusCodes . Status200OK , MediaTypeNames . Application . Json ) ]
108+ [ ProducesResponseType < AltinnProblemDetails > ( StatusCodes . Status400BadRequest , MediaTypeNames . Application . Json ) ]
109+ [ ProducesResponseType ( StatusCodes . Status401Unauthorized ) ]
110+ [ ProducesResponseType ( StatusCodes . Status403Forbidden ) ]
111+ public async Task < IActionResult > GetDraftRequest ( [ FromQuery ] [ Required ] Guid id , CancellationToken ct = default )
112+ {
113+ var result = await requestService . GetRequest ( id , ct ) ;
114+ if ( result . IsProblem )
115+ {
116+ return Forbid ( ) ;
117+ }
118+
119+ if ( result . Value . Status != RequestStatus . Draft )
120+ {
121+ return Forbid ( ) ;
122+ }
123+
124+ bool isAuthorized = await AuthorizeResourceAccess ( "altinn_access_management" , result . Value . From . Id , User , "write" ) ;
125+ if ( isAuthorized )
126+ {
127+ return Forbid ( ) ;
128+ }
129+
130+ return Ok ( result . Value ) ;
131+ }
132+
99133 [ HttpGet ]
100134 [ FeatureGate ( RequirementType . Any , AccessMgmtFeatureFlags . EnableRequestAssignmentResource , AccessMgmtFeatureFlags . EnableRequestAssignmentPackage ) ]
101135 [ Authorize ( Policy = AuthzConstants . POLICY_ACCESS_MANAGEMENT_ENDUSER_READ ) ]
@@ -452,4 +486,22 @@ private async Task<IActionResult> UpdateRequestStatus(Guid partyUuid, Guid id, R
452486
453487 return Ok ( result . Value ) ;
454488 }
489+
490+ private async Task < bool > AuthorizeResourceAccess ( string resource , Guid resourceParty , ClaimsPrincipal userPrincipal , string action )
491+ {
492+ XacmlJsonRequestRoot request = DecisionHelper . CreateDecisionRequestForResourceRegistryResource ( resource , resourceParty , userPrincipal , action ) ;
493+ XacmlJsonResponse response = await Pdp . GetDecisionForRequest ( request ) ;
494+
495+ if ( response ? . Response == null )
496+ {
497+ throw new InvalidOperationException ( "response" ) ;
498+ }
499+
500+ if ( ! DecisionHelper . ValidatePdpDecision ( response . Response , userPrincipal ) )
501+ {
502+ return false ;
503+ }
504+
505+ return true ;
506+ }
455507}
0 commit comments