# 🧩 SOA – Service-Oriented Architecture Project ## πŸ—οΈ Architecture Overview This project implements a **Service-Oriented Architecture (SOA)** for an art gallery management system using Docker containerization and microservices architecture. ### System Components ``` 🌐 HTTPS (Port 443) β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Apache Reverse Proxy β”‚ β”‚ (SSL Termination + OIDC Validation) β”‚ β”‚ β”‚ β”‚ /api/public/* ──────┐ β”Œβ”€β”€β”€β”€β”€β”€ /api/private/* β”‚ β”‚ (No Auth) β”‚ β”‚ (OIDC Required) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ | β”‚ β”‚ (+ OIDC Headers) | β”‚ β”‚ | β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β” β”Œβ”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” | β”‚ β”‚ β”‚ β”‚ | β”‚ Public API β”‚ β”‚ Private API β”‚ | β”‚ (Laravel) β”‚ β”‚ (Flask) β”‚ | β”‚ Port 5001 β”‚ β”‚ Port 5002 β”‚ | β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ | β”‚ β”‚ | β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”‚ MySQL β”‚ β”‚ Keycloak β”‚ β”‚ (Application DB) β”‚ β”‚ + Postgres β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Redis β”‚ β”‚ (Cache + Events) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Technology Stack | Component | Technology | Purpose | |-----------|------------|---------| | **Reverse Proxy** | Apache HTTP Server | SSL termination, request routing | | **Authentication** | Keycloak | OIDC/OAuth2 identity provider | | **Public API** | Laravel 12 (PHP) | Public galleries and artworks API | | **Private API** | Flask (Python) | User management and private content | | **Databases** | PostgreSQL + MySQL | Data persistence | | **Cache/Queue** | Redis | Caching and event messaging | // NOT IMPLEMENTED YET ### Service Architecture #### πŸ”“ **Public API Service** (Laravel) - **Port**: Internal 5001 (via Apache) - **Database**: MySQL - **Purpose**: Public access to galleries and artworks - **Features**: - RESTful API for public galleries - Artist directory - Public artwork browsing - Pagination and filtering #### πŸ”’ **Private API Service** (Flask) - **Port**: Internal 5002 (via Apache) - **Database**: MySQL - **Authentication**: OIDC via Apache mod_auth_openidc - **Purpose**: Authenticated user operations - **Features**: - User profile management - Gallery creation and management - Artwork upload and editing - Review system for galleries/artworks - Invitation system for gallery members #### πŸ” **Authentication Service** (Keycloak) - **Port**: 8080 - **Database**: PostgreSQL - **Purpose**: Centralized identity and access management - **Features**: - OIDC/OAuth2 provider - User registration and login - Token-based authentication - Single Sign-On (SSO) ### Request Flow All requests enter through **Apache on port 443** (HTTPS) and are processed as follows: 1. **SSL Termination**: Apache handles SSL/TLS encryption 2. **Request Routing**: Based on URL path: - `/api/public/*` β†’ Routes to **Public API** (Laravel on port 5001) - `/api/private/*` β†’ Routes to **Private API** (Flask on port 5002) 3. **OIDC Authentication Check**: - **Public API**: No authentication required - **Private API**: Apache mod_auth_openidc validates OIDC tokens with Keycloak 4. **Header Injection**: Apache injects user info headers (OIDC_email, OIDC_user) for authenticated requests 5. **API Processing**: Backend services handle business logic 6. **Data Persistence**: MySQL stores application data 7. **Event Publishing**: Redis handles inter-service communication ### Security Model - **SSL/TLS**: All external communication encrypted - **OIDC Authentication**: Industry standard OAuth2/OIDC flow - **Token-based Authorization**: JWT tokens for API access - **Network Isolation**: Services communicate via internal network - **Database Security**: Separate databases for auth and application data ## πŸš€ Quick Start 1. **Start the application stack:** ```bash docker compose up -d --build ``` 2. **Initialize Keycloak configuration:** ```bash ./setup-keycloak.sh ``` 3. **Update your `/etc/hosts` file:** ``` 127.0.0.1 api.local auth.local ``` --- ## πŸ” Credentials ### Keycloak Admin Panel * πŸ“ URL: [http://auth.local:8080](http://auth.local:8080) * πŸ‘€ **Username:** `admin` * πŸ”‘ **Password:** `admin` ### Private API User * πŸ‘€ **Username:** `alexis` * πŸ”‘ **Password:** `password` --- ## πŸ—‚οΈ Public API Endpoints Overview All routes are prefixed with `/api/public`. | Method | Endpoint | Description | | ------ | ------------------------------- | ---------------------------------- | | GET | `/artists` | List all public artists | | GET | `/galleries` | List all public galleries | | GET | `/galleries/{gallery}/artworks` | List artworks for a public gallery | --- ## πŸ—‚οΈ Private API Endpoints Overview All routes are prefixed with `/api/private` and require a **Bearer token**. ### πŸ‘€ User | Method | Endpoint | Description | | ------ | -------- | ----------------------------- | | GET | `/me` | Get current user's profile | | PUT | `/me` | Update current user's profile | ### πŸ–ΌοΈ Galleries | Method | Endpoint | Description | | ------ | ----------------------- | --------------------------------- | | GET | `/galleries` | List all accessible galleries | | GET | `/galleries/mine` | List galleries owned by the user | | POST | `/gallery` | Create a new gallery | | GET | `/gallery/{gallery_id}` | Get details of a specific gallery | | PUT | `/gallery/{gallery_id}` | Update a gallery (owner only) | ### πŸ‘₯ Members | Method | Endpoint | Description | | ------ | ------------------------------- | ------------------------- | | GET | `/gallery/{gallery_id}/members` | List members of a gallery | ### πŸ“© Invitations | Method | Endpoint | Description | | ------ | ----------------------------------- | --------------------------- | | POST | `/gallery/{gallery_id}/invite` | Invite user to a gallery | | PUT | `/invitations/{gallery_id}/respond` | Accept or reject invitation | | GET | `/invitations/received` | List received invitations | ### πŸ–ΌοΈ Artworks | Method | Endpoint | Description | | ------ | -------------------------------- | ----------------------------------- | | GET | `/gallery/{gallery_id}/artworks` | List artworks in a gallery | | POST | `/gallery/{gallery_id}/artwork` | Add artwork to gallery (owner only) | | GET | `/artwork/{artwork_id}` | Get details of an artwork | | PUT | `/artwork/{artwork_id}` | Update an artwork (creator only) | | GET | `/artworks/mine` | List artworks created by the user | ### πŸ“ Gallery Reviews | Method | Endpoint | Description | | ------ | ------------------------------- | ------------------------------------- | | GET | `/gallery/{gallery_id}/reviews` | List reviews for a gallery | | POST | `/gallery/{gallery_id}/review` | Submit a review for a gallery | | PUT | `/galleries/review/{review_id}` | Update a gallery review (author only) | | GET | `/galleries/reviews/given` | Reviews written by the user | | GET | `/galleries/reviews/received` | Reviews received on user’s galleries | ### πŸ“ Artwork Reviews | Method | Endpoint | Description | | ------ | ------------------------------- | -------------------------------------- | | GET | `/artwork/{artwork_id}/reviews` | List reviews for an artwork | | POST | `/artwork/{artwork_id}/review` | Submit a review for an artwork | | PUT | `/artworks/review/{review_id}` | Update an artwork review (author only) | | GET | `/artworks/reviews/given` | Reviews written by the user | | GET | `/artworks/reviews/received` | Reviews received on user’s artworks | --- # Public API: ## Routes : ``` GET|HEAD api/artists GET|HEAD api/galleries GET|HEAD api/galleries/{gallery}/artworks ```