IsUserInGroup (OP-18)¶
Request and response¶
| Part | Type | Description |
|---|---|---|
inUserId |
String |
The SamAccountName to look up. |
inGroupName |
String |
The group's SamAccountName to look up. |
inExternalDomain |
Boolean |
Selects external.saif.com when True, corp.saif.com when False (BR-07) for both the user and the group lookup. |
| Part | Type | Description |
|---|---|---|
<return> |
ADServiceResponse |
Response (EResponse code) and Message (the literal "True" or "False" on success). |
WebMethod attributes¶
<WebMethod()> — bare, no arguments supplied.
Steps¶
- No access check is performed (BR-06).
- Initialize
myStruc.Response = Success,myStruc.Message = String.Empty. - In a
Tryblock, call H2GetUserPrincipalwith the caller-suppliedinExternalDomain. - If the principal is
Nothing, setResponse = UserDoesNotExist. - Otherwise, call H3
GetGroupPrincipalwithinGroupNameandinExternalDomain. - If the group principal is
Nothing, setResponse = GroupDoesNotExist. - Otherwise, set
Message = "True"whengroupPrin.Members.Contains(userPrin), elseMessage = "False"(BR-32). This checks direct membership only. - This differs from
DoesUserHaveResource(OP-08), which walks transitive authorization groups viaGetAuthorizationGroups: a user entitled only through a nested group answers"False"here even thoughDoesUserHaveResourcewould answer"True"for the same user and group — an inconsistent membership semantic across the two operations (SEC-17, HIGH — see Authentication and authorization and Tech debt). Catch: setResponse = Failure,Message = ex.Message.Finally: releasegroupPrinanduserPrin.- Return the
ADServiceResponsesentinel.
Process flow¶
flowchart TD
A["Call IsUserInGroup"] --> B["GetUserPrincipal<br>caller-selected domain"]
B -->|"Nothing"| C["Response = UserDoesNotExist"]
B -->|"Found"| D["GetGroupPrincipal<br>caller-selected domain"]
D -->|"Nothing"| E["Response = GroupDoesNotExist"]
D -->|"Found"| F{"groupPrin.Members<br>.Contains(userPrin)?<br>direct only"}
F -->|"Yes"| G["Message = True"]
F -->|"No"| H["Message = False"]
B -->|"Exception"| I["Response = Failure<br>Message = ex.Message"]
C --> J["Return ADServiceResponse"]
E --> J
G --> J
H --> J
I --> J
Shared state effects¶
None — this operation touches no process-wide state; all locals are per-request.
Error handling¶
This operation never faults: an unresolved user, an unresolved group, or any other directory exception is caught and mapped to Response = Failure with ex.Message in Message. See Faults for the service-wide fault model.
Authorization¶
None in code. This is one of the eleven ungated operations that disclose directory data to any caller who can reach the endpoint. Its direct-only membership semantic also disagrees with DoesUserHaveResource's transitive semantic for the same underlying question (SEC-17, see Authentication and authorization and Tech debt).
Related documentation¶
- Service index
- Overview
- Architecture
- Activation and hosting
- Operations
- Operations and processes
- Business rules
- Authentication and authorization
- Configuration
- Dependencies
- Faults
- Operational runbook
- Tech debt
Sources¶
src\ADUserServices\clsADUserServices.asmx.vb(lines 715-750)