d8fc61d25bdf35857782c3c6234e269ae53b01c0
configuration/getUsersWithRecentSession.sh
| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | +#!/bin/bash |
|
| 2 | +# A script that can extract users with a session with last access time at or |
|
| 3 | +# after the ISO time stamp provided as argument #2, reading from the MongoDB |
|
| 4 | +# provided as argument #1. The relevant collections are SESSIONS and USERS. |
|
| 5 | +# |
|
| 6 | +# Example: |
|
| 7 | +# getUsersWithRecentSession.sh "mongodb://mongo1.internal.sapsailing.com/security_service?replicaSet=live" 2025-01-01T00:00:00Z |
|
| 8 | +# |
|
| 9 | +# Will output a JSON array containing user records as object with fields NAME, FULLNAME, |
|
| 10 | +# COMPANY, LOCAL, EMAIL, and EMAIL_VALIDATED |
|
| 11 | +# |
|
| 12 | +# To restrict the output to those whose e-mail address was validated, use something |
|
| 13 | +# like: |
|
| 14 | +# getUsersWithRecentSession.sh ... | jq '[.[] | select(.EMAIL_VALIDATED==true)] |
|
| 15 | +# |
|
| 16 | +MONGO_URL="${1}" |
|
| 17 | +SINCE_TIMESTAMP_ISO="${2}" |
|
| 18 | +USERS_WITH_RECENT_SESSION_AS_JSON_ARRAY_OF_STRINGS=$( mongosh --quiet --eval ' |
|
| 19 | +EJSON.stringify(db.SESSIONS.aggregate([ |
|
| 20 | + // Step 1: Filter documents by timestamp |
|
| 21 | + { |
|
| 22 | + $match: { |
|
| 23 | + SESSION_LAST_ACCESS_TIME: { $gt: ISODate("'${SINCE_TIMESTAMP_ISO}'") } |
|
| 24 | + } |
|
| 25 | + }, |
|
| 26 | + // Step 2: Unwind SESSION_ATTRIBUTES to work with each outer object individually |
|
| 27 | + { $unwind: "$SESSION_ATTRIBUTES" }, |
|
| 28 | + // Step 3: Keep only SESSION_ATTRIBUTES elements matching SESSION_ATTRIBUTE_NAME |
|
| 29 | + { |
|
| 30 | + $match: { |
|
| 31 | + "SESSION_ATTRIBUTES.SESSION_ATTRIBUTE_NAME": "org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY" |
|
| 32 | + } |
|
| 33 | + }, |
|
| 34 | + // Step 4: Extract the inner string (assume innerArray has one element) |
|
| 35 | + { |
|
| 36 | + $addFields: { |
|
| 37 | + username: { $arrayElemAt: ["$SESSION_ATTRIBUTES.SESSION_ATTRIBUTE_VALUE.SESSION_PRINCIPAL_REALM_NAME", 0] } |
|
| 38 | + } |
|
| 39 | + }, |
|
| 40 | + // Step 5: Keep only non-empty strings |
|
| 41 | + { |
|
| 42 | + $match: { |
|
| 43 | + username: { $nin: ["", null] } |
|
| 44 | + } |
|
| 45 | + }, |
|
| 46 | + // Step 6: Project only the string if desired |
|
| 47 | + { |
|
| 48 | + $project: { |
|
| 49 | + _id: 0, |
|
| 50 | + username: 1 |
|
| 51 | + } |
|
| 52 | + } |
|
| 53 | +]).toArray())' "${MONGO_URL}" | jq '[.[].username] | unique' ) |
|
| 54 | +mongosh --quiet --eval "EJSON.stringify(db.USERS.find({NAME: {\$in: ${USERS_WITH_RECENT_SESSION_AS_JSON_ARRAY_OF_STRINGS}}}).toArray())" "${MONGO_URL}" | jq '[.[] | { NAME, FULLNAME, COMPANY, LOCALE, EMAIL, EMAIL_VALIDATED }]' |
|
| 55 | + |