smurfy/atlassian-services-crowd
Laravel package for integrating Atlassian Crowd authentication and SSO into your application. Manage users and groups, authenticate against Crowd, and sync identity data seamlessly with your Laravel projects.
This package is a Composer repackaging of the long-dead PEAR library Services_Atlassian_Crowd — the description ("copy of the pearpackage") is literal. Treat it as a thin HTTP client for the Atlassian Crowd REST API, not as a Laravel integration. There is no service provider, no facade, no config file, and no documentation beyond the PEAR source.
composer require smurfy/atlassian-services-crowd
First, read the installed source to confirm what you actually got:
ls vendor/smurfy/atlassian-services-crowd
cat vendor/smurfy/atlassian-services-crowd/composer.json
You are looking for Services/Atlassian/Crowd.php (and possibly Crowd/ subclasses) and the autoload strategy — it is almost certainly classmap or PEAR-include based, not PSR-4, so the class name is Services_Atlassian_Crowd with underscores.
Before writing any Laravel code, verify connectivity and credentials out-of-band. Crowd rejects bad application credentials with a 401, and that failure mode is easy to confuse with bad user credentials:
curl -su "$CROWD_APP_NAME:$CROWD_APP_PASSWORD" \
"https://crowd.example.com/crowd/rest/usermanagement/1/user?username=alice"
Your first real use case is a login endpoint — authenticate a username/password against Crowd and mint a normal Laravel session:
$crowd = new Services_Atlassian_Crowd([
'app_name' => config('crowd.app_name'),
'app_credential' => config('crowd.app_password'),
'host' => parse_url(config('crowd.base_url'), PHP_URL_HOST),
'port' => 443,
'use_ssl' => true,
]);
$user = $crowd->authenticate($request->username, $request->password);
Auth::login(/* map $user onto a local User model */);
Create config/crowd.php yourself and read secrets from .env — nothing ships with the package.
Wrap it in a single service class. Never instantiate Services_Atlassian_Crowd in controllers. Bind a singleton in a small service provider and inject an interface (CrowdClient) so you can fake it in tests:
$this->app->singleton(CrowdClient::class, fn () => new PearCrowdClient(config('crowd')));
Custom auth guard / user provider. The idiomatic integration is a CrowdUserProvider implementing Illuminate\Contracts\Auth\UserProvider. Resolve the incoming username via getUser(), validate credentials by calling authenticate() in validateCredentials(), and provision/patch a local users row on first login. Keep Crowd as the authority for credentials but let your users table own everything else (roles, profile, relations) — Crowd should never be your primary key store.
Crowd SSO token flow. If you want real SSO across apps, don't authenticate passwords on every request. Instead:
crowd.token_key cookie on inbound requests.validateSession($token) to confirm the user.createSession($user, $pass, ['remote_address' => $request->ip()]) and write the returned token to the cookie.This is the flow that makes Crowd worth having; password auth per-app is the fallback.
Group-to-authorization mapping. Expose Crowd groups as Gate abilities rather than scattering findUserGroups() calls:
Gate::define('admin', fn ($user) => in_array('crowd-admins', $user->crowd_groups));
Sync groups into the session at login so you are not calling Crowd on every @can check.
Cache aggressively. Every call is a synchronous HTTPS round trip to the Crowd server. Cache group membership (Cache::remember("crowd:groups:{$username}", 300, ...)) and the user lookup, and invalidate on logout or group change webhooks.
Testing. Because the class is not mockable and uses raw curl/streams internally, wrap it behind your CrowdClient interface and use Http::fake() only if you rewrite it against Laravel's HTTP client. For now, a stub implementation of your interface is the practical path.
each(), dynamic properties, loose string/int comparisons) that emit deprecations on PHP 8.2+ and fatal on 8.3+ dynamic-property changes. Smoke-test the constructor and a simple authenticate() before building on it.Auth::extend shim. Everything in "Implementation Patterns" above is code you write.Services_Atlassian_Crowd_Exception or a PEAR_Error. Catch broadly (\Throwable) at the boundary and translate to your domain exceptions; do not let raw PEAR errors bubble into HTTP responses.401 from 404/405. Crowd returns 401 both for invalid application credentials and for wrong user passwords. If every login fails, check the app credential and the /crowd/services/ base URL path suffix (often .../crowd/services/Services/ or .../crowd/rest/) — that base path mismatch is the single most common setup bug.verify_ssl_cert/verify_peer to make it work — fix the CA bundle in the container instead.method_exists() or read the source before assuming a call exists; fall back to a small Guzzle wrapper for anything missing rather than patching the vendor dir.remote_address validation factors. If you create SSO sessions without passing the client IP (and Crowd is configured to validate it), validateSession() will fail silently for some users. Mirror whatever the Crowd server's session-validation settings expect.CrowdClient interface described above. When this package inevitably bites you, replacing PearCrowdClient with a Guzzle-based implementation of the same interface is a one-file change — which is also the recommended migration path, since a ~150-line Guzzle client beats an abandoned PEAR dependency.How can I help you explore Laravel packages today?