Appearance
Lesson 15 Practice — Secure the Support Issue Business Object
You already built a state-aware Support Issue BO.
Current flow:
text
O = Open
I = In Progress
C = ClosedActions:
text
startProcessing
closeNow secure it.
Target architecture:
text
User
↓
CDS DCL
↓
ZR_ISSUE_###
↓
RAP Authorization
├─ Global
└─ Instance
↓
Managed Behavior
↓
ZISSUE_###Practice information
| Time | About 3 hours |
| Prerequisite | Lesson 15 teacher-led work |
| Business Object | ZR_ISSUE_### |
| Behavior Pool | ZBP_R_ISSUE_### |
| Test class | ZCL_ISSUE_AUTH_### |
| New field | ResponsibleUser |
| New object | CDS Access Control |
1. Verify the starting point
Confirm these activate:
text
ZISSUE_###
ZR_ISSUE_###
Behavior Definition
ZBP_R_ISSUE_###
ZCL_ISSUE_ACTIONS_###Your BO should already include:
text
managed CRUD
managed UUID numbering
determination
validations
messages
actions
feature control2. Authorization requirements
Implement:
text
Read:
only rows whose ResponsibleUser = current user
Global create/update/delete:
allowed in the Trial exercise
Instance update:
allowed only for ResponsibleUser
Action authorization:
reuse update authorization
Delete:
allowed for classroom cleanup3. Add persistence ownership
Add:
text
responsible_userto:
text
ZISSUE_###Use:
text
ABP_CREATION_USERor the equivalent source type used in the guided lesson.
Keep it nullable.
Explain why that matters for rows created before Lesson 15.
4. Extend the root CDS
Expose:
text
ResponsibleUserChange:
text
@AccessControl.authorizationCheck: #NOT_REQUIREDto:
text
@AccessControl.authorizationCheck: #CHECKActivate.
5. Create CDS Access Control
Create an Access Control object for:
text
ZR_ISSUE_###Requirements:
text
@MappingRole: true
define role
grant select on ZR_ISSUE_###
ResponsibleUser = aspect userDo not hard-code a user.
6. DCL reasoning
Answer:
Does the DCL delete unauthorized Issues?
Does DCL replace RAP update authorization?
Does define role mean the same thing as a PFCG/business role?
7. Change RAP authorization
Replace:
text
authorization master ( none )with:
text
authorization master ( global, instance )Use:
text
Ctrl+F2before continuing.
8. Update persistence mapping
Map:
text
ResponsibleUserto:
text
responsible_user9. Protect ResponsibleUser
Make:
text
ResponsibleUserread-only on update.
It must remain writable during create for this exercise.
10. Protect Status if required
If a normal external consumer can still directly update:
text
Statusmake it read-only.
Status should be controlled by:
text
initial Status determination
startProcessing
close11. Delegate action authorization
Modify:
text
startProcessing
closeso both delegate authorization to:
text
updateKeep their existing:
text
features : instancelogic.
12. Generate authorization methods
Use:
text
Ctrl+1Generate:
text
get_global_authorizations
get_instance_authorizationsPrefer ADT-generated signatures.
13. Implement global authorization
For the Trial exercise:
text
requested create
→ auth-allowed
requested update
→ auth-allowed
requested delete
→ auth-allowedUse authorization constants.
Do not use:
text
fc-o-enabledhere.
14. Explain the global Trial simplification
Write one sentence explaining why:
text
allow-all global authorizationis not a production authorization model.
Mention:
text
authorization objects
business roles15. Implement instance authorization
Read:
text
ResponsibleUserusing:
text
READ ENTITIES ... IN LOCAL MODERule:
text
ResponsibleUser = current technical user
→ update allowed
otherwise
→ update unauthorizedFor this practice:
text
delete
→ allowed16. Obtain the current user
Use the same ABAP Cloud API as the guided lesson:
text
CL_ABAP_CONTEXT_INFOand its technical-user getter.
Store the result in a compatible user variable.
17. Report an authorization message
For unauthorized update, report a message equivalent to:
text
You are not responsible for this issueThe authorization result must still be:
text
auth-unauthorizedA message is not the decision itself.
18. Activate all changed objects
Activate:
text
ZISSUE_###
ZR_ISSUE_###
Access Control
Behavior Definition
ZBP_R_ISSUE_###Do not create the runtime consumer until everything activates cleanly.
19. Create the test class
Create:
text
ZCL_ISSUE_AUTH_###Implement:
text
IF_OO_ADT_CLASSRUNThis is an external consumer.
It must not use:
text
IN LOCAL MODE20. Reserved Issue numbers
Use:
text
99010001
99010002Meaning:
text
99010001
→ owned by current user
99010002
→ ResponsibleUser initialUse valid values so all Lesson 13 validations pass.
21. Repeatable reset
Because DCL will hide one test row, use the guided reset approach:
text
read UUIDs for exactly 99010001 / 99010002
delete those UUIDs through EML
commitDo not use direct SQL writes.
22. Display current user
Output the current technical user at the beginning of the test.
Record:
text
Current user:
____________________23. Create owned Issue
Create:
text
IssueNo = 99010001
ResponsibleUser = current user
Status = omittedExpected determination:
text
Status = OSave its generated UUID.
24. Create unassigned Issue
Create:
text
IssueNo = 99010002
ResponsibleUser = initial
Status = omittedExpected:
text
Status = OSave its generated UUID before commit.
25. Commit both creates
Inspect:
text
MAPPED
FAILED
REPORTEDBoth create requests should save successfully in the training global-authorization model.
26. Prove DCL filtering
Open:
text
ZR_ISSUE_###with:
text
F8Expected:
text
99010001 visible
99010002 hiddenThen open:
text
ZISSUE_###with:
text
Alt+F8Expected:
text
both physical rows existExplain why.
27. Test global authorization
Build a permission request for:
text
create
update
deleteRun:
text
GET PERMISSIONS ONLY GLOBAL AUTHORIZATIONRecord:
text
create:
update:
delete:28. Test owned instance authorization
Request:
text
update
deletefor:
text
99010001 UUIDusing:
text
GET PERMISSIONS ONLY INSTANCE AUTHORIZATIONExpected:
text
update allowed
delete allowed29. Test unassigned instance authorization
Repeat for:
text
99010002 UUIDExpected:
text
update unauthorized
delete allowed30. Compare feature control with authorization
For unassigned Issue:
text
Status = OLesson 14 feature control should say:
text
startProcessing enabledBut authorization says:
text
update unauthorizedRecord:
text
Feature result:
____________________
Authorization result:
____________________31. Owned action test
Execute:
text
startProcessingfor owned Issue.
Expected:
text
O → ICommit.
32. Unauthorized action test
Execute:
text
startProcessingfor the unassigned Issue using its known UUID.
Expected:
text
action denied
Status remains O
authorization message returnedExplain why this happens even though state-based feature control enables the action.
33. Unauthorized update test
Attempt:
text
Notes = 'Should not persist'on the unassigned Issue.
Expected:
text
update denied
Notes unchangedInspect RAP responses.
34. Owned close test
For the owned Issue now in:
text
Iexecute:
text
closeExpected:
text
I → CCommit.
35. Cleanup the unassigned Issue
Delete it using its known UUID through EML.
Because delete is deliberately allowed for training cleanup, the delete should succeed.
Commit.
36. Final visible state
Root CDS should show:
text
99010001
Status = C
ResponsibleUser = current userThe unassigned test row should be gone after cleanup.
37. Repair exercise — wrong access annotation
Temporarily reason about leaving:
text
#NOT_REQUIREDafter creating the DCL.
Restore:
text
#CHECKExplain the intended difference.
38. Repair exercise — missing @MappingRole
Inspect what happens if the DCL source is incomplete.
Restore:
text
@MappingRole: trueExplain its purpose.
39. Repair exercise — hard-coded user
Wrong:
text
ResponsibleUser = 'MYUSER'Correct concept:
text
ResponsibleUser = aspect userExplain why hard-coded identity is not a scalable authorization design.
40. Repair exercise — wrong constant family
Wrong:
text
fc-o-disabledCorrect authorization result:
text
auth-unauthorizedExplain:
text
feature availability
vs
user authorization41. Repair exercise — IN LOCAL MODE in consumer
Search:
text
ZCL_ISSUE_AUTH_###It should not contain:
text
IN LOCAL MODEExplain why the Behavior Pool may use it but the consumer may not.
42. Repair exercise — DCL only
Imagine you keep DCL but remove RAP authorization.
Explain why read filtering alone is not a complete write-protection strategy.
Use:
text
read
update
actionin your explanation.
43. Certification-style mini task
Temporarily change the Issue authorization policy so:
text
deleteis also owner-only.
Requirements:
text
check requested delete authorization
compare ResponsibleUser with current user
return auth-allowed or auth-unauthorized
test owned permission
test unassigned permissionRestore delete-allowed behavior afterward if you still need repeatable classroom cleanup.
44. Certification knowledge — PFCG
Research only:
text
aspect pfcg_auth
AUTHORITY-CHECK
ACTVTAnswer:
Which mechanism belongs in CDS DCL?
Which mechanism can appear inside RAP authorization implementation?
Why does this Trial lesson not create a complete custom PFCG authorization lifecycle?
45. Authorization audit
Complete:
| Concern | Mechanism | Result |
|---|---|---|
| Owned Issue visible | ||
| Unassigned Issue hidden | ||
| Global create | ||
| Owned update | ||
| Unassigned update | ||
Owned startProcessing | ||
Unassigned startProcessing | ||
| Delete cleanup |
46. Feature vs authorization audit
Complete:
| Instance | Status | Action feature | Update authorization | Final action result |
|---|---|---|---|---|
| Owned | O before action | |||
| Unassigned | O |
Explain why the unassigned row can have:
text
enabled feature
+
unauthorized operation47. Submission checklist
48. End-of-practice explanation
Explain without notes:
text
DCL protects reads.
Global RAP authorization answers whether
the user may perform an operation generally.
Instance RAP authorization adds
instance-dependent user permission.
Feature control is not authorization.
A feature can be enabled while
authorization still denies execution.
IN LOCAL MODE belongs to provider logic,
not external consumers.If you can prove those statements in your own Issue BO, you are ready for Lesson 16.