Changes between Version 1 and Version 2 of OtherDevelopments


Ignore:
Timestamp:
05/28/26 09:38:22 (2 hours ago)
Author:
221296
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OtherDevelopments

    v1 v2  
    273273
    274274These indexes improve reports that analyze quiz attempts by user, quiz or date.
     275
     276= Security and Protection Measures =
     277
     278== Spring Security Authentication ==
     279
     280The application uses Spring Security for authentication and authorization.
     281
     282Unauthenticated users can access public pages such as:
     283
     284home page
     285login page
     286registration page
     287static resources such as CSS and JavaScript files
     288
     289All other requests require authentication.
     290
     291Example configuration:
     292
     293{{{
     294@Bean
     295public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
     296
     297http
     298    .csrf(Customizer.withDefaults())
     299    .authorizeHttpRequests(auth -> auth
     300        .requestMatchers("/", "/login", "/register", "/css/**", "/js/**").permitAll()
     301        .anyRequest().authenticated()
     302    )
     303    .formLogin(form -> form
     304        .defaultSuccessUrl("/", true)
     305        .permitAll()
     306    )
     307    .logout(logout -> logout
     308        .logoutUrl("/logout")
     309        .logoutSuccessUrl("/login?logout")
     310        .permitAll()
     311    );
     312
     313return http.build();
     314
     315}
     316}}}
     317
     318Explanation:
     319
     320Spring Security protects the application by requiring users to log in before accessing protected resources.
     321
     322The configuration also defines login and logout behavior.
     323
     324== Password Hashing with BCrypt ==
     325
     326User passwords are not stored in plain text. The application uses BCrypt for password hashing.
     327
     328Example:
     329
     330{{{
     331@Bean
     332public PasswordEncoder passwordEncoder() {
     333return new BCryptPasswordEncoder();
     334}
     335}}}
     336
     337During login, the raw password entered by the user is compared with the stored hashed password.
     338
     339{{{
     340passwordEncoder.matches(rawPassword, storedHashedPassword);
     341}}}
     342
     343Explanation:
     344
     345This protects user accounts because even if someone gets access to the database, the original passwords are not directly visible.
     346
     347== Role-Based Access Control ==
     348
     349The database contains a role attribute in the user_entity table.
     350
     351{{{
     352role VARCHAR(20) NOT NULL CHECK (role IN ('USER', 'ADMIN', 'INSTRUCTOR'))
     353}}}
     354
     355The system supports three roles:
     356
     357USER — can browse courses, enroll in courses and access learning content
     358INSTRUCTOR — can manage courses, modules, lessons and quizzes
     359ADMIN — can manage categories, subscription plans and support tickets
     360
     361Explanation:
     362
     363The CHECK constraint prevents invalid roles from being inserted into the database.
     364
     365The separate tables users, administrators and instructors also support the supertype/subtype structure of the system.
     366
     367== SQL Injection Prevention ==
     368
     369SQL Injection is prevented by using Spring Data JPA and parameterized queries instead of directly concatenating user input into SQL strings.
     370
     371Safe example:
     372
     373{{{
     374@Query("SELECT u FROM UserEntity u WHERE u.email = ")
     375Optional findByEmail(@Param("email") String email);
     376}}}
     377
     378Unsafe example:
     379
     380{{{
     381String query = "SELECT * FROM user_entity WHERE email = '" + email + "'";
     382}}}
     383
     384Explanation:
     385
     386The safe approach treats user input as data, not as executable SQL code.
     387
     388This prevents malicious input from changing the meaning of the SQL query.
     389
     390== Database Constraints and Data Integrity ==
     391
     392The database schema contains constraints that protect the data from invalid states.
     393
     394Examples:
     395
     396{{{
     397email VARCHAR(150) UNIQUE NOT NULL
     398}}}
     399
     400This prevents duplicate user accounts with the same email.
     401
     402{{{
     403progress_percentage INT CHECK (progress_percentage BETWEEN 0 AND 100)
     404}}}
     405
     406This prevents invalid course progress values.
     407
     408{{{
     409certificate_code VARCHAR(100) UNIQUE NOT NULL
     410}}}
     411
     412This ensures that every certificate has a unique certificate code.
     413
     414{{{
     415enrollment_id INT UNIQUE NOT NULL
     416}}}
     417
     418This ensures that one enrollment can have only one certificate.
     419
     420Foreign keys are also used to protect relationships between tables:
     421
     422{{{
     423FOREIGN KEY (user_id) REFERENCES users(id)
     424FOREIGN KEY (course_id) REFERENCES course(course_id)
     425FOREIGN KEY (enrollment_id) REFERENCES enrollment(enrollment_id)
     426}}}
     427
     428Explanation:
     429
     430These constraints prevent orphan records and keep the database consistent.
     431
     432== Transaction Management ==
     433
     434Some operations must be executed as one atomic unit.
     435
     436For example, when a user enrolls in a course, the system may need to:
     437
     438check whether the user has an active subscription
     439check whether the user is already enrolled
     440insert a new enrollment record
     441update related data
     442
     443Example:
     444
     445{{{
     446@Transactional
     447public void enrollUserInCourse(Long userId, Long courseId) {
     448// check active subscription
     449// check existing enrollment
     450// create new enrollment
     451}
     452}}}
     453
     454Explanation:
     455
     456If one step fails, the whole transaction is rolled back.
     457
     458This protects the database from partial or inconsistent changes.
     459
     460== Database Connection Configuration ==
     461
     462The application uses PostgreSQL as the database system.
     463
     464Example configuration:
     465
     466{{{
     467spring.application.name=db
     468spring.datasource.url=jdbc:postgresql://localhost:3307/db_202526z_va_prj_olpms
     469spring.datasource.username=USERNAME
     470spring.datasource.password=PASSWORD
     471spring.datasource.driver-class-name=org.postgresql.Driver
     472
     473spring.jpa.hibernate.ddl-auto=validate
     474spring.jpa.show-sql=true
     475spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
     476}}}
     477
     478Explanation:
     479
     480Real database credentials should not be published on the wiki page. Because of that, the username and password are replaced with placeholders.
     481
     482Spring Boot uses HikariCP as the default database connection pool implementation. Connection pooling improves performance by reusing already opened database connections instead of opening a new connection for every request.