← Back to Main Page

Module 2: Build Sprint 1

Understanding Your First Ticket

Learn how to approach your first ticket in the Labs project and understand the development workflow.

First Ticket Details

View your first ticket details and requirements on GitHub:

First Ticket Documentation

Approaching Your First Feature

Learn how to implement the core domain objects and security configuration for the Bloom Coder Assignment App.

Implementation Checklist

  • Create User, Authority, and Assignment entities
  • Implement proper constructors and relationships
  • Set up Spring Security configuration
  • Create required DTOs and Enums
  • Configure UserDetailsService implementation
  • Implement proper security overrides
  • Test authentication flow
// Example User entity implementation

@Entity
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private LocalDate cohortStartDate;
    private String username;
    private String password;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List authorities;
    
    // Constructors
    public User() {}
    
    public User(LocalDate cohortStartDate, String username, String password) {
        this.cohortStartDate = cohortStartDate;
        this.username = username;
        this.password = password;
    }
    
    // UserDetails overrides
    @Override
    public Collection getAuthorities() {
        return authorities;
    }
    
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    
    // ... other overrides
}

Spring Boot Review

Review essential Spring Boot concepts and JWT authentication implementation for the project.

JWT Utils Implementation

// Example JWT Utils class

@Component
public class JwtUtils {
    @Value("${jwt.secret}")
    private String jwtSecret;
    
    @Value("${jwt.expiration}")
    private int jwtExpirationMs;
    
    public String generateJwtToken(Authentication authentication) {
        UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
        
        return Jwts.builder()
            .setSubject((userPrincipal.getUsername()))
            .setIssuedAt(new Date())
            .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
            .signWith(SignatureAlgorithm.HS512, jwtSecret)
            .compact();
    }
    
    public String getUserNameFromJwtToken(String token) {
        return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
    }
    
    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            // Handle invalid JWT signature
        } catch (MalformedJwtException e) {
            // Handle invalid JWT token
        } catch (ExpiredJwtException e) {
            // Handle expired JWT token
        } catch (UnsupportedJwtException e) {
            // Handle unsupported JWT token
        } catch (IllegalArgumentException e) {
            // Handle JWT claims string is empty
        }
        return false;
    }
}

Spring Data JPA Repository Example

// Example Repository interface

@Repository
public interface UserRepository extends JpaRepository {
    Optional findByUsername(String username);
    Boolean existsByUsername(String username);
    Boolean existsByEmail(String email);
}

// Example Service implementation
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    public User createUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }
    
    public Optional findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
}