Skip to content

Commit 2fec3d7

Browse files
CopilotRei-x
andauthored
feat: add usos integration
* Initial plan * Initial analysis - planning OAuth 1.0a provider for USOS integration Co-authored-by: Rei-x <[email protected]> * Add OAuth 1.0a provider for USOS integration with complete implementation Co-authored-by: Rei-x <[email protected]> * Complete OAuth 1.0a USOS provider implementation with UI integration and documentation Co-authored-by: Rei-x <[email protected]> * Add extensive testing and linting setup for USOS provider plugin Co-authored-by: Rei-x <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Rei-x <[email protected]>
1 parent d4126c0 commit 2fec3d7

25 files changed

+1803
-1
lines changed

.github/workflows/ci.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,53 @@ jobs:
1919
run: npm ci
2020

2121
- run: npm run build-keycloak-theme
22+
23+
java-build-and-test:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Set up JDK 17
29+
uses: actions/setup-java@v4
30+
with:
31+
java-version: '17'
32+
distribution: 'temurin'
33+
34+
- name: Cache Maven packages
35+
uses: actions/cache@v4
36+
with:
37+
path: ~/.m2
38+
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
39+
restore-keys: ${{ runner.os }}-m2
40+
41+
- name: Build and test USOS provider
42+
working-directory: keycloak-usos-provider
43+
run: |
44+
echo "Building USOS OAuth 1.0a provider..."
45+
mvn clean compile
46+
echo "Running comprehensive tests..."
47+
mvn test
48+
echo "Running static analysis..."
49+
mvn checkstyle:check
50+
mvn spotbugs:check
51+
mvn pmd:check
52+
echo "Building final JAR..."
53+
mvn package
54+
55+
- name: Upload test results
56+
uses: actions/upload-artifact@v4
57+
if: always()
58+
with:
59+
name: java-test-results
60+
path: |
61+
keycloak-usos-provider/target/surefire-reports/
62+
keycloak-usos-provider/target/checkstyle-result.xml
63+
keycloak-usos-provider/target/spotbugsXml.xml
64+
keycloak-usos-provider/target/pmd.xml
65+
66+
- name: Upload coverage to Codecov
67+
uses: codecov/codecov-action@v4
68+
if: always()
69+
with:
70+
file: keycloak-usos-provider/target/site/jacoco/jacoco.xml
71+
flags: java

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,7 @@ jspm_packages
5656
/build
5757
/storybook-static
5858

59-
.keycloaklify/*
59+
.keycloaklify/*
60+
61+
# Maven build artifacts
62+
keycloak-usos-provider/target/

Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ COPY . .
55
RUN npm ci
66
RUN npm run build-keycloak-theme
77

8+
# Build the custom USOS OAuth 1.0a provider
9+
WORKDIR /app/keycloak-usos-provider
10+
RUN mvn clean package
11+
812
FROM quay.io/keycloak/keycloak:26.1.2
913
WORKDIR /opt/keycloak
1014
COPY --from=build /app/dist_keycloak/keycloak-theme-for-kc-all-other-versions.jar /opt/keycloak/providers/
15+
COPY --from=build /app/keycloak-usos-provider/target/keycloak-usos-provider-1.0.0.jar /opt/keycloak/providers/
1116

1217
RUN /opt/keycloak/bin/kc.sh build --db=postgres --health-enabled=true --features=docker
1318

USOS_SETUP_GUIDE.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# USOS OAuth 1.0a Provider Setup Guide
2+
3+
This guide explains how to configure the custom USOS OAuth 1.0a identity provider in Keycloak.
4+
5+
## Overview
6+
7+
The USOS provider enables students to login using their university USOS accounts via OAuth 1.0a protocol. This custom provider has been integrated into the Keycloak Docker image and supports the full OAuth 1.0a flow required by USOS API.
8+
9+
## Prerequisites
10+
11+
1. Access to a USOS system (e.g., usosweb.example.edu.pl)
12+
2. USOS OAuth application credentials (consumer key and secret)
13+
3. Running Keycloak instance with the custom provider
14+
15+
## Configuration Steps
16+
17+
### 1. Register USOS OAuth Application
18+
19+
First, you need to register your application in the USOS system:
20+
21+
1. Contact your USOS administrator or go to the USOS developer portal
22+
2. Register a new OAuth application
23+
3. Set the callback URL to: `https://your-keycloak-domain/auth/realms/{realm-name}/broker/usos/endpoint`
24+
4. Note down the Consumer Key and Consumer Secret
25+
26+
### 2. Configure USOS Identity Provider in Keycloak
27+
28+
1. Login to Keycloak Admin Console
29+
2. Select your realm
30+
3. Go to Identity Providers
31+
4. Click "Add provider..." and select "USOS"
32+
5. Configure the following settings:
33+
34+
#### Required Configuration:
35+
36+
- **Alias**: `usos` (or any unique identifier)
37+
- **Display Name**: `USOS` (displayed on login screen)
38+
- **Consumer Key**: Your USOS OAuth Consumer Key
39+
- **Consumer Secret**: Your USOS OAuth Consumer Secret
40+
- **USOS Base URL**: Base URL of your USOS instance (e.g., `https://usosweb.example.edu.pl`)
41+
42+
#### Optional Configuration:
43+
44+
- **First Login Flow**: Choose how new users are handled
45+
- **Sync Mode**: How user data is synchronized
46+
- **Store Token**: Whether to store OAuth tokens
47+
- **Trust Email**: Whether to trust email from USOS
48+
49+
### 3. Advanced Configuration (Optional)
50+
51+
If your USOS installation uses non-standard endpoints, you can override them:
52+
53+
- **Request Token URL**: Custom request token endpoint
54+
- **Authorization URL**: Custom authorization endpoint
55+
- **Access Token URL**: Custom access token endpoint
56+
- **User Info URL**: Custom user info endpoint
57+
58+
### 4. User Attribute Mapping
59+
60+
The provider automatically maps these USOS user attributes:
61+
62+
- `id` → Keycloak username
63+
- `first_name` → First name
64+
- `last_name` → Last name
65+
- `email` → Email address
66+
- `student_number` → Custom attribute
67+
- `student_status` → Custom attribute
68+
- `staff_status` → Custom attribute
69+
70+
You can configure additional attribute mappings in the provider settings.
71+
72+
## Testing the Integration
73+
74+
1. Go to your Keycloak login page
75+
2. You should see a "USOS" button among social providers
76+
3. Click the USOS button
77+
4. You'll be redirected to USOS for authentication
78+
5. After successful login, you'll be redirected back to Keycloak
79+
80+
## Troubleshooting
81+
82+
### Common Issues:
83+
84+
**"Request token not found in session"**
85+
86+
- Check that your callback URL is correctly configured
87+
- Ensure cookies are enabled in the browser
88+
89+
**"Failed to retrieve request token"**
90+
91+
- Verify Consumer Key and Consumer Secret
92+
- Check USOS Base URL is correct
93+
- Ensure USOS system is accessible from Keycloak
94+
95+
**"Authentication failed"**
96+
97+
- Check Keycloak logs for detailed error messages
98+
- Verify USOS user info endpoint is responding correctly
99+
100+
### Debug Configuration:
101+
102+
Enable debug logging in Keycloak by adding this to your configuration:
103+
104+
```
105+
--log-level=DEBUG --log-console-color=true
106+
```
107+
108+
Look for log entries from `pl.edu.solvro.keycloak.usos` package.
109+
110+
## USOS API Endpoints
111+
112+
The provider uses these standard USOS API endpoints:
113+
114+
- Request Token: `/services/oauth/request_token`
115+
- Authorization: `/services/oauth/authorize`
116+
- Access Token: `/services/oauth/access_token`
117+
- User Info: `/services/users/user?format=json`
118+
119+
## Security Considerations
120+
121+
1. Always use HTTPS in production
122+
2. Keep Consumer Secret secure
123+
3. Regularly rotate OAuth credentials
124+
4. Monitor authentication logs
125+
5. Set up proper CORS policies
126+
127+
## Example Docker Compose
128+
129+
```yaml
130+
version: "3.8"
131+
services:
132+
keycloak:
133+
build: .
134+
environment:
135+
- KC_DB=postgres
136+
- KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
137+
- KC_DB_USERNAME=keycloak
138+
- KC_DB_PASSWORD=password
139+
- KC_HOSTNAME=localhost
140+
- KEYCLOAK_ADMIN=admin
141+
- KEYCLOAK_ADMIN_PASSWORD=admin
142+
ports:
143+
- "8080:8080"
144+
depends_on:
145+
- postgres
146+
147+
postgres:
148+
image: postgres:15
149+
environment:
150+
- POSTGRES_DB=keycloak
151+
- POSTGRES_USER=keycloak
152+
- POSTGRES_PASSWORD=password
153+
```
154+
155+
## Support
156+
157+
For issues specific to this USOS provider, please check:
158+
159+
1. Keycloak server logs
160+
2. USOS system availability
161+
3. Network connectivity between Keycloak and USOS
162+
4. OAuth credential validity
163+
164+
For USOS-specific questions, consult your USOS administrator or the USOS API documentation at https://apps.usos.edu.pl/developers/api/
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE module PUBLIC
3+
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
4+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
5+
6+
<module name="Checker">
7+
<property name="severity" value="warning"/>
8+
<property name="fileExtensions" value="java, properties, xml"/>
9+
10+
<!-- Checks for whitespace -->
11+
<module name="FileTabCharacter">
12+
<property name="eachLine" value="true"/>
13+
</module>
14+
15+
<!-- Checks for Size Violations. -->
16+
<module name="LineLength">
17+
<property name="max" value="120"/>
18+
</module>
19+
20+
<module name="TreeWalker">
21+
<!-- Checks for Naming Conventions. -->
22+
<module name="ConstantName">
23+
<property name="severity" value="ignore"/>
24+
</module>
25+
<module name="LocalFinalVariableName"/>
26+
<module name="LocalVariableName"/>
27+
<module name="MemberName"/>
28+
<module name="MethodName">
29+
<property name="severity" value="ignore"/>
30+
</module>
31+
<module name="PackageName"/>
32+
<module name="ParameterName"/>
33+
<module name="StaticVariableName"/>
34+
<module name="TypeName"/>
35+
36+
<!-- Checks for imports -->
37+
<module name="AvoidStarImport"/>
38+
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
39+
<module name="RedundantImport"/>
40+
<module name="UnusedImports"/>
41+
42+
<!-- Checks for Size Violations. -->
43+
<module name="MethodLength">
44+
<property name="max" value="100"/>
45+
</module>
46+
<module name="ParameterNumber">
47+
<property name="max" value="8"/>
48+
</module>
49+
50+
<!-- Checks for whitespace -->
51+
<module name="EmptyForIteratorPad"/>
52+
<module name="GenericWhitespace"/>
53+
<module name="MethodParamPad"/>
54+
<module name="NoWhitespaceAfter"/>
55+
<module name="NoWhitespaceBefore"/>
56+
<module name="OperatorWrap"/>
57+
<module name="ParenPad"/>
58+
<module name="TypecastParenPad"/>
59+
<module name="WhitespaceAfter"/>
60+
<module name="WhitespaceAround"/>
61+
62+
<!-- Modifier Checks -->
63+
<module name="ModifierOrder"/>
64+
<module name="RedundantModifier"/>
65+
66+
<!-- Checks for blocks. -->
67+
<module name="AvoidNestedBlocks"/>
68+
<module name="EmptyBlock"/>
69+
<module name="LeftCurly"/>
70+
<module name="NeedBraces"/>
71+
<module name="RightCurly"/>
72+
73+
<!-- Checks for common coding problems -->
74+
<module name="EmptyStatement"/>
75+
<module name="EqualsHashCode"/>
76+
<module name="HiddenField">
77+
<property name="ignoreSetter" value="true"/>
78+
<property name="ignoreConstructorParameter" value="true"/>
79+
</module>
80+
<module name="IllegalInstantiation"/>
81+
<module name="InnerAssignment"/>
82+
<module name="MissingSwitchDefault"/>
83+
<module name="SimplifyBooleanExpression"/>
84+
<module name="SimplifyBooleanReturn"/>
85+
86+
<!-- Checks for class design -->
87+
<module name="DesignForExtension">
88+
<property name="severity" value="ignore"/>
89+
</module>
90+
<module name="FinalClass"/>
91+
<module name="HideUtilityClassConstructor"/>
92+
<module name="InterfaceIsType"/>
93+
<module name="VisibilityModifier">
94+
<property name="protectedAllowed" value="true"/>
95+
</module>
96+
97+
<!-- Miscellaneous other checks. -->
98+
<module name="ArrayTypeStyle"/>
99+
<module name="TodoComment">
100+
<property name="severity" value="info"/>
101+
</module>
102+
<module name="UpperEll"/>
103+
</module>
104+
</module>

0 commit comments

Comments
 (0)