Wiki source code of How-To: Site Licenses

Last modified by Admin User on 2026/09/01 16:47

Show last authors
1 = 1. Overview =
2
3 Site licenses provide IP-based concurrent access for institutions such as libraries, universities, and corporate offices. An institution purchases a license for N concurrent seats, and anyone accessing gated content from the institution’s IP range gets transparent access — no login required, no forms to fill out — up to the concurrent seat limit.
4
5 Key characteristics:
6
7 * Access is determined by IP address, not by individual user accounts
8 * Concurrent sessions are limited to the purchased seat count
9 * Sessions are maintained by a heartbeat mechanism — if a user leaves, their seat is automatically released after a configurable timeout (default: 30 minutes)
10 * When all seats are occupied, new visitors see a branded “seats full” message
11 * Each seat is represented by a synthetic OCID for reporting purposes
12
13 [[image:fulfillment-site-licenses_386f6176b5b0bbbe.png||height="430" width="586"]]
14
15 //The Site Licenses list showing three demo institutions with concurrent seat counts and statuses.//
16
17 In this example, Springfield Public Library has 15 concurrent seats (active), Metro University has 50 seats (active), and Horizon Aviation Museum is a cancelled license with 5 seats.
18
19 = 2. How Site Licenses Work =
20
21 == 2.1 Access Flow ==
22
23 When a visitor accesses a page with gated content, the following happens:
24
25 * 1. The ONEcount widget (oc.min.js) loads and sends an access check request
26 * 2. The gating layer checks the visitor’s IP against all active site license IP ranges
27 * 3. If a match is found, the system checks for available concurrent seats
28 * 4. If a seat is available, the visitor is silently assigned a synthetic identity and granted access
29 * 5. The widget starts a heartbeat timer to keep the session alive
30 * 6. When the visitor leaves (closes browser, navigates away), the seat is released
31
32 == 2.2 Synthetic Identities ==
33
34 Each concurrent seat maps to a pre-created synthetic user in the ONEcount database. These users have names like “Springfield Library, Seat 1” and internal email addresses like “sl-42-seat-1@sitelicense.internal.” They have real subscription records, which means they appear naturally in all standard reports.
35
36 //Synthetic users are created automatically when the site license is created. You do not need to create them manually.//
37
38 == 2.3 Session Lifecycle ==
39
40 Sessions are tracked in Cassandra with a Time-To-Live (TTL). The TTL is set to the session_ttl value on the license (default: 1800 seconds / 30 minutes). Every heartbeat from the widget resets this TTL, keeping the session alive. If no heartbeat arrives within the TTL window, the session automatically expires and the seat becomes available.
41
42 Additionally, when a user closes the browser tab or navigates away, the widget attempts to release the seat immediately using the browser’s sendBeacon API. This provides faster seat turnover in normal usage.
43
44 = 3. Creating a Site License =
45
46 Navigate to Fulfillment › Site Licenses. Click the red “Create Site License” button to open the creation modal.
47
48 [[image:fulfillment-site-licenses_8e8e80905336a638.png||height="411" width="586"]]
49
50 //The Create Site License modal with institution name, seat count, product-or-package selection, and initial IP range.//
51
52 |**Field**|**Required**|**Description**
53 |**Institution name**|Yes|Display name (e.g., “Springfield Public Library”)
54 |**Purchaser OCID**|Yes|The OCID of the billing contact at the institution
55 |**Concurrent seats**|Yes|Maximum number of simultaneous users
56 |**Product or Package**|Yes|Select a product or package from the dropdown (grouped by type)
57 |**Term**|Yes|Select the term — cascades from the selected product or package
58 |**Publication**|No|The fulfillment publication (for magazine content)
59 |**Start date**|Yes|When the license becomes active
60 |**End date**|No|When the license expires (empty = perpetual)
61 |**IP range (CIDR)**|No|Initial IP range in CIDR notation. More can be added after creation.
62
63 When you create the license, the system automatically:
64
65 * Creates N synthetic users named “[Institution], Seat 1” through “[Institution], Seat N”
66 * Creates subscription records for each synthetic user
67 * Grants product access (user_product entries) so the gating layer recognizes them
68
69 = 4. Managing IP Ranges =
70
71 Each site license can have multiple IP ranges. Ranges are specified in CIDR notation:
72
73 |**Format**|**Example**|**Matches**
74 |**Single IP**|192.168.1.100|Exactly one IP address
75 |**Subnet /24**|192.168.1.0/24|192.168.1.0 through 192.168.1.255 (256 addresses)
76 |**Subnet /16**|10.0.0.0/16|10.0.0.0 through 10.0.255.255 (65,536 addresses)
77 |**Larger subnet**|172.16.0.0/12|172.16.0.0 through 172.31.255.255
78
79 [[image:fulfillment-site-licenses_4a8d67282ca4569a.png||height="430" width="586"]]
80
81 //Springfield Public Library detail page showing IP ranges (Main branch /24, Eastside annex /28), active sessions, and synthetic seats.//
82
83 In this example, Springfield Public Library has two IP ranges configured: 198.51.100.0/24 for the main branch (256 addresses) and 198.51.101.0/28 for the Eastside annex (16 addresses). Each range shows the computed start and end IP and an optional label.
84
85 IP ranges are managed from the site license detail page. Click the “+ Add” button to add a new range, or the × button to remove an existing one.
86
87 //If an IP matches multiple site licenses, the system uses the most specific match (narrowest IP range).//
88
89 = 5. Session Management =
90
91 == 5.1 Heartbeat Configuration ==
92
93 The detail page header shows the heartbeat and session TTL values for the license. In the Springfield Public Library example:
94
95 * Heartbeat interval: 120 seconds — the widget pings every 2 minutes
96 * Session TTL: 1800 seconds (30 minutes) — sessions expire after 30 minutes without a heartbeat
97
98 |**Parameter**|**Default**|**Description**
99 |**heartbeat_interval**|120 seconds|How often the widget pings to keep the session alive
100 |**session_ttl**|1800 seconds (30 min)|How long a session persists without a heartbeat before auto-expiry
101
102 These values are set per-license and can be adjusted based on the institution’s needs. A shorter session_ttl frees seats faster but may cause disruptions for slow readers. A longer interval reduces server load but delays seat release for idle users.
103
104 == 5.2 Seats Full Message ==
105
106 When all concurrent seats are occupied, new visitors see a full-screen overlay with a customizable message. The default message is:
107
108 “//All N seats for [Institution Name] are currently in use. Please try again later.”//
109
110 You can customize this message per-license via the seats_full_message field. The page auto-retries every 30 seconds.
111
112 = 6. The User Experience =
113
114 The site license experience is designed to be completely transparent to the end user:
115
116 * No login form is displayed
117 * No registration is required
118 * No ONEcount branding is shown
119 * Content loads normally as if it were unprotected
120 * The only user-visible moment is when seats are full — a branded overlay appears
121
122 Behind the scenes, the widget sets session cookies (~_~_oc_sl_session, ~_~_oc_sl_id, ~_~_oc_sl_hb) to maintain the session. These are automatically managed and do not require user interaction.
123
124 = 7. Monitoring Active Sessions =
125
126 The site license detail page shows active sessions in real-time (visible in the “Active Sessions” card). For each session, you can see:
127
128 * Seat number
129 * Synthetic OCID
130 * Visitor’s IP address
131 * Session start time
132 * Last heartbeat time
133
134 You can force-release a session from this page if needed (e.g., if a session appears stuck). Click the “Release” button next to the session. The “Refresh” button updates the session list.
135
136 = 8. Reporting =
137
138 Site license seats are represented by synthetic OCIDs with real subscriptions. They flow through all standard fulfillment reports:
139
140 * RPT-01 (Circulation) — Synthetic OCIDs are counted in their classification bucket
141 * RPT-09 (Adds & Removals) — Reason codes SITE_LICENSE_NEW, SITE_LICENSE_EXPIRED, SITE_LICENSE_CANCELLED track lifecycle events
142 * RPT-19 (Mail File) — Site license seats typically do not receive mail (no physical address), but they appear in the serve log for audit purposes
143
144 The subscription_source field on the serve log is tagged as “site_license” for these OCIDs, enabling easy filtering in custom reports.
145
146 = 9. Troubleshooting =
147
148 |**Symptom**|**Likely Cause**|**Resolution**
149 |**Users see login form instead of transparent access**|IP range not configured or doesn’t match the visitor’s IP|Check the IP ranges on the license detail page. Verify the visitor’s public IP matches a configured range.
150 |**Seats fill up faster than expected**|session_ttl too long; idle sessions holding seats|Reduce session_ttl (e.g., to 900 seconds / 15 min)
151 |**Sessions don’t release when users leave**|Browser doesn’t support sendBeacon or blocks it|Normal — sessions will auto-expire after session_ttl. Consider reducing the TTL.
152 |“**Seats full” when seats should be available**|Stale sessions in Cassandra|Force-release sessions from the admin detail page. Sessions also auto-expire.
153 |**Synthetic users not appearing in reports**|Migration not applied|Apply fulfillment/sql/034_site_license.sql and fulfillment/cql/010_site_license_session.cql
154
155 = 10. Permissions =
156
157 Site license management requires the FULFILLMENT_SITE_LICENSE_MANAGE permission module. Creating site licenses additionally requires FULFILLMENT_SETUP. Superadmin users automatically have access to all functions.
158
159 = Appendix: Navigation =
160
161 All three subscription model features are accessible from the Fulfillment section of the admin sidebar:
162
163 [[image:fulfillment-site-licenses_737296447e02486d.png||height="430" width="586"]]
164
165 //The Fulfillment sidebar menu showing Gift Subscriptions, Group Licenses, and Site Licenses navigation entries.//