A secure, role-based online voting system built with Spring Boot, featuring JWT authentication, role-based access control, and comprehensive voting management.
The Online Voting System is a robust web application that enables secure electronic voting with the following key features:
- Role-based Access Control: Separate interfaces for ADMIN and VOTER roles
- JWT Authentication: Secure token-based authentication with configurable expiration
- Election Management: Create and manage elections with start/end dates
- Candidate Management: Add candidates to specific elections
- Secure Voting: Cast votes with validation and restrictions
- Real-time Results: View election results with vote tallies
- City-based Voter Filtering: Filter voters by geographical location
- Bean Validation: Comprehensive input validation on all DTOs and entities
- Global Exception Handling: Centralized error handling with proper HTTP status codes
- Spring Boot Project: Initialized with all required dependencies
- Bean Validation: Applied on DTOs with @Valid, @NotNull, @NotBlank, @Email, @Size, @Future
- Component Scanning: @Component, @Service, @Repository with @ComponentScan filters
- Entity Classes: Voter, Candidate, Election, Vote with proper JPA annotations
- Repository Pattern: CrudRepository implementation with custom finder methods
- Custom Queries: @Query for custom results, @Modifying for update/delete operations
- REST Endpoints: @RestController with proper HTTP methods and status codes
- Global Exception Handling: @ControllerAdvice with comprehensive error handling
- Spring Security: JWT-based authentication with role-based authorization
- Role-based Access Control: ADMIN and VOTER roles with proper endpoint protection
- Register Candidates: Admin can submit forms to register new candidates
- Assign Voters: Admin can assign eligible voters based on city
- Election Management: Create and manage elections with time windows
- Results Display: Count and display election results in real-time
- Security: All admin endpoints secured with ADMIN role requirement
- Secure Login: Voter login returns JWT token on success
- Vote Casting: Voters can cast one vote per election with validation
- Time Restrictions: Voting only allowed during election time window
- Duplicate Prevention: System prevents multiple votes by same voter
- City Assignment: Voters must be assigned to a city before voting
- Bean Validation: @Valid annotations on all controller endpoints
- Custom Queries: @Modifying @Query for update/delete operations
- Exception Handling: Custom exceptions with proper HTTP status codes
- JWT Security: Token generation, validation, and role extraction
- Data Integrity: Proper relationships and constraints between entities
- Input Validation: Comprehensive validation on all input DTOs
The system follows a layered architecture pattern:
βββββββββββββββββββ
β Controllers β β REST API endpoints with validation
βββββββββββββββββββ€
β Services β β Business logic and validation
βββββββββββββββββββ€
β Repositories β β Data access with custom queries
βββββββββββββββββββ€
β Domain β β Entity models with validation
βββββββββββββββββββ
- Security Layer: JWT-based authentication with role-based authorization
- Validation Layer: Bean validation on all DTOs and entities
- Business Logic: Service layer handling voting rules and validation
- Data Persistence: JPA/Hibernate with custom repository methods
- Exception Handling: Global exception handler with proper HTTP status codes
{
"sub": "voter@example.com",
"role": "VOTER",
"iat": 1640995200,
"exp": 1640998800
}| Endpoint | Role Required | Description |
|---|---|---|
/auth/** |
None | Public authentication endpoints |
/admin/** |
ADMIN | Admin management endpoints |
/api/voters/** |
VOTER | Voter-specific endpoints |
POST /auth/admin/login- Admin loginPOST /auth/voter/login- Voter loginPOST /auth/voter/register- Voter registration
POST /admin/elections- Create electionGET /admin/elections- List all electionsPOST /admin/candidates- Register candidateGET /admin/candidates- List all candidatesPOST /admin/voters- Register voterPUT /admin/voters/{id}/assign- Assign voter to cityGET /admin/voters/city/{city}- List voters by cityGET /admin/results- View election results
GET /api/voters/candidates- View available candidatesPOST /api/voters/vote- Cast voteGET /api/voters/city/{city}- View voters by cityGET /api/voters/{id}- Get voter details
@Entity
@Table(name = "users")
public class Voter {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank @Size(min = 2, max = 100)
private String name;
@NotBlank @Email @Column(unique = true)
private String email;
@NotBlank
private String passwordHash;
@Enumerated(EnumType.STRING)
private Role role;
@NotBlank
private String city;
}@Entity
public class Candidate {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank @Size(min = 2, max = 100)
private String name;
@NotNull
@ManyToOne
private Election election;
}@Entity
@Table(name = "Election")
public class Election {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String title;
@NotNull @Future
private LocalDate startDate;
@NotNull @Future
private LocalDate endDate;
}@Entity
@Table(name = "vote")
public class Vote {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private LocalDateTime voteTime;
@ManyToOne @JoinColumn(nullable = false)
private Candidate candidate;
@ManyToOne @JoinColumn(nullable = false)
private Election election;
@ManyToOne @JoinColumn(nullable = false)
private Voter voter;
}All DTOs and entities include comprehensive validation:
- @NotNull: Required fields
- @NotBlank: Non-empty strings
- @Email: Valid email format
- @Size: String length constraints
- @Future: Date validation for elections
Centralized error handling with proper HTTP status codes:
- 400 Bad Request: Validation errors, bad input
- 401 Unauthorized: Invalid/missing JWT
- 403 Forbidden: Insufficient role permissions
- 404 Not Found: Resource not found
- 500 Internal Server Error: Server-side errors
VotingClosedException: Voting outside time windowUnassignedVoterException: Voter not assigned to cityBadRequestException: Invalid business logicResourceNotFoundException: Entity not found
- Java 17 or higher
- Maven 3.6+
- IDE (IntelliJ IDEA, Eclipse, or VS Code)
-
Clone the repository
git clone <repository-url> cd onlineVotingSystem
-
Configure the application
Update
src/main/resources/application.properties:# Database Configuration (for production, use PostgreSQL/MySQL) spring.datasource.url=jdbc:postgresql://localhost:5432/voting_system spring.datasource.username=your_username spring.datasource.password=your_password # JWT Configuration jwt.secret=your-256-bit-secret-key-here-make-it-long-and-secure jwt.expiration=3600000
-
Run the application
mvn spring-boot:run
Or build and run:
mvn clean package java -jar target/onlineVotingSystem-0.0.1-SNAPSHOT.jar
-
Access the application
- API Base URL:
http://localhost:8080 - H2 Console (dev):
http://localhost:8080/h2-console - Health Check:
http://localhost:8080/actuator/health
- API Base URL:
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=GlobalExceptionHandlerTest
# Run with coverage
mvn jacoco:report- Unit Tests: Service layer, exception handling
- Integration Tests: Repository layer, security
- Exception Tests: Global exception handler
- Validation Tests: DTO validation constraints
curl -X POST http://localhost:8080/auth/admin/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"password": "admin123"
}'curl -X POST http://localhost:8080/admin/elections \
-H "Authorization: Bearer <ADMIN_JWT>" \
-H "Content-Type: application/json" \
-d '{
"title": "Presidential Election 2024",
"startDate": "2024-11-05",
"endDate": "2024-11-06"
}'curl -X POST http://localhost:8080/admin/candidates \
-H "Authorization: Bearer <ADMIN_JWT>" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"party": "Democratic Party",
"electionId": 1
}'curl -X POST http://localhost:8080/auth/voter/login \
-H "Content-Type: application/json" \
-d '{
"email": "voter@example.com",
"password": "voter123"
}'curl -X POST http://localhost:8080/api/voters/vote \
-H "Authorization: Bearer <VOTER_JWT>" \
-H "Content-Type: application/json" \
-d '{
"candidateId": 1,
"electionId": 1
}' \
-G -d "voterEmail=voter@example.com"jwt.secret=your-secret-key-here
jwt.expiration=3600000spring.datasource.url=jdbc:postgresql://localhost:5432/voting_system
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=updatespring.security.user.name=admin
spring.security.user.password=admin- Exception Handling Guide - Comprehensive error handling documentation
- Postman Collection - API testing collection
- Security Configuration - Security setup details
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the repository
- Contact the development team
- Check the documentation and examples
Note: This system is designed for educational and demonstration purposes. For production use, additional security measures, logging, and monitoring should be implemented.