Issue Tracker Source Code


The Nextcloud instance contains the source code of the issue tracker application .

┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/hawat]
└─$ mv ~/Downloads/issuetracker.zip .

Downloading the archive to Kali

┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/hawat]
└─$ unzip -q ./issuetracker.zip 
 
┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/hawat]
└─$ tree -a -f ./issuetracker  
./issuetracker
├── ./issuetracker/HELP.md
├── ./issuetracker/mvnw
├── ./issuetracker/mvnw.cmd
├── ./issuetracker/pom.xml
└── ./issuetracker/src
    ├── ./issuetracker/src/main
    │   ├── ./issuetracker/src/main/java
    │   │   └── ./issuetracker/src/main/java/com
    │   │       └── ./issuetracker/src/main/java/com/issue
    │   │           └── ./issuetracker/src/main/java/com/issue/tracker
    │   │               ├── ./issuetracker/src/main/java/com/issue/tracker/TrackerApplication.java
    │   │               ├── ./issuetracker/src/main/java/com/issue/tracker/config
    │   │               │   └── ./issuetracker/src/main/java/com/issue/tracker/config/WebSecurityConfig.java
    │   │               ├── ./issuetracker/src/main/java/com/issue/tracker/issues
    │   │               │   ├── ./issuetracker/src/main/java/com/issue/tracker/issues/Issue.java
    │   │               │   ├── ./issuetracker/src/main/java/com/issue/tracker/issues/IssueController.java
    │   │               │   ├── ./issuetracker/src/main/java/com/issue/tracker/issues/IssueInterface.java
    │   │               │   ├── ./issuetracker/src/main/java/com/issue/tracker/issues/IssueRepository.java
    │   │               │   └── ./issuetracker/src/main/java/com/issue/tracker/issues/IssueService.java
    │   │               └── ./issuetracker/src/main/java/com/issue/tracker/users
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/Role.java
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/UserController.java
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/UserDetailsServiceImpl.java
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/UserInterface.java
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/UserService.java
    │   │                   ├── ./issuetracker/src/main/java/com/issue/tracker/users/Users.java
    │   │                   └── ./issuetracker/src/main/java/com/issue/tracker/users/UsersRepository.java
    │   └── ./issuetracker/src/main/resources
    │       ├── ./issuetracker/src/main/resources/application.properties
    │       ├── ./issuetracker/src/main/resources/static
    │       │   ├── ./issuetracker/src/main/resources/static/css
    │       │   │   └── ./issuetracker/src/main/resources/static/css/bootstrap.min.css
    │       │   └── ./issuetracker/src/main/resources/static/js
    │       │       ├── ./issuetracker/src/main/resources/static/js/bootstrap.min.js
    │       │       ├── ./issuetracker/src/main/resources/static/js/jquery-3.4.1.js
    │       │       ├── ./issuetracker/src/main/resources/static/js/main.js
    │       │       └── ./issuetracker/src/main/resources/static/js/sweetalert.min.js
    │       └── ./issuetracker/src/main/resources/templates
    │           ├── ./issuetracker/src/main/resources/templates/fragments.html
    │           ├── ./issuetracker/src/main/resources/templates/index.html
    │           ├── ./issuetracker/src/main/resources/templates/issue_form.html
    │           ├── ./issuetracker/src/main/resources/templates/issue_index.html
    │           ├── ./issuetracker/src/main/resources/templates/layout.html
    │           ├── ./issuetracker/src/main/resources/templates/login.html
    │           ├── ./issuetracker/src/main/resources/templates/user_form.html
    │           └── ./issuetracker/src/main/resources/templates/user_index.html
    └── ./issuetracker/src/test
        └── ./issuetracker/src/test/java
            └── ./issuetracker/src/test/java/com
                └── ./issuetracker/src/test/java/com/issue
                    └── ./issuetracker/src/test/java/com/issue/tracker
                        └── ./issuetracker/src/test/java/com/issue/tracker/TrackerApplicationTests.java
 
20 directories, 33 files

Extracting the archive reveals the source code of the issue tracker application

pom.xml


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/hawat/issuetracker]
└─$ cat pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.4.2</version>
                <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.issue</groupId>
        <artifactId>tracker</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>tracker</name>
        <description>Issue Tracker Application</description>
        <properties>
                <java.version>11</java.version>
        </properties>
        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-data-jpa</artifactId>
                </dependency>
                <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-security</artifactId>
                </dependency>
                <dependency>
                  <groupId>org.springframework.security</groupId>
                  <artifactId>spring-security-test</artifactId>
                  <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.thymeleaf.extras</groupId>
                    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-devtools</artifactId>
                        <scope>runtime</scope>
                        <optional>true</optional>
                </dependency>
                <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <scope>runtime</scope>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
        </dependencies>
 
        <build>
                <plugins>
                        <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                </plugins>
        </build>
 
</project>

Checking the pom.xml file reveals that the issue tracker application is built on Spring Framework It also uses Java 11 and MySQL as a backend database

resources


┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/hawat/issuetracker]
└─$ cd src/main/resources; ll
total 20K
4.0K -rw-r--r-- 1 kali kali  289 Feb  8  2021 application.properties
4.0K drwxr-xr-x 2 kali kali 4.0K Feb  5  2021 templates
4.0K drwxr-xr-x 4 kali kali 4.0K Feb  3  2021 .
4.0K drwxr-xr-x 4 kali kali 4.0K Feb  2  2021 static
4.0K drwxr-xr-x 4 kali kali 4.0K Feb  2  2021 ..

application.properties

application.properties


┌──(kali㉿kali)-[~/…/issuetracker/src/main/resources]
└─$ cat application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/issue_tracker?serverTimeZone=UTC
spring.datasource.username=issue_user
spring.datasource.password=ManagementInsideOld797
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 
spring.jpa.hibernate.ddl-auto=update
server.port=17445

The application.properties file contains a MySQL DB credential; issue_user:ManagementInsideOld797

Source Code


┌──(kali㉿kali)-[~/…/hawat/issuetracker/src/main]
└─$ cd java/com/issue/tracker; ll
total 24K
4.0K drwxrwxr-x 2 kali kali 4.0K Mar  2  2021 issues
4.0K drwxrwxr-x 2 kali kali 4.0K Mar  2  2021 config
4.0K drwxrwxr-x 2 kali kali 4.0K Feb  5  2021 users
4.0K drwxr-xr-x 5 kali kali 4.0K Feb  3  2021 .
4.0K drwxr-xr-x 3 kali kali 4.0K Feb  2  2021 ..
4.0K -rw-r--r-- 1 kali kali  312 Feb  2  2021 TrackerApplication.java

TrackerApplication.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat TrackerApplication.java
package com.issue.tracker;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class TrackerApplication {
 
        public static void main(String[] args) {
                SpringApplication.run(TrackerApplication.class, args);
        }
 
}

Entrypoint

config


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ ll config 
total 12K
4.0K drwxrwxr-x 2 kali kali 4.0K Mar  2  2021 .
4.0K -rw-rw-r-- 1 kali kali 1.7K Mar  2  2021 WebSecurityConfig.java
4.0K drwxr-xr-x 5 kali kali 4.0K Feb  3  2021 ..
 
┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat config/WebSecurityConfig.java 
package com.issue.tracker.config;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
 
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	BCryptPasswordEncoder bCryptPasswordEncoder;
	
	@Autowired
	UserDetailsService userDetailsService;
	
 
	protected void configure(HttpSecurity http) throws Exception {
		http
             .csrf().disable()
			.authorizeRequests()
				.antMatchers("/", "/index", "/register", "/user/register", "/css/**", "/js/**").permitAll()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login")
				.failureUrl("/login-error")
				.permitAll()
				.and()
			.logout()
				.permitAll()
				.logoutSuccessUrl("/index");
	}
 
	@Override
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
	}
	
	@Bean
	public BCryptPasswordEncoder getEncoder() {
		return new BCryptPasswordEncoder();
	}
}

The config/WebSecurityConfig.java file defines the authentication mechanism

issues


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ ll issues
total 28K
4.0K drwxrwxr-x 2 kali kali 4.0K Mar  2  2021 .
4.0K -rw-rw-r-- 1 kali kali 2.8K Mar  2  2021 IssueController.java
4.0K drwxr-xr-x 5 kali kali 4.0K Feb  3  2021 ..
4.0K -rw-rw-r-- 1 kali kali  233 Feb  2  2021 IssueRepository.java
4.0K -rw-rw-r-- 1 kali kali  248 Feb  2  2021 IssueInterface.java
4.0K -rw-rw-r-- 1 kali kali  689 Feb  2  2021 IssueService.java
4.0K -rw-rw-r-- 1 kali kali 1.1K Feb  2  2021 Issue.java

Issue.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat issues/Issue.java
package com.issue.tracker.issues;
 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
 
@Entity
@Table(name = "issue")
public class Issue {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int Id;
        private String message;
        private String priority;
 
        // Source > Generate Constructor Superclass
        public Issue() {
                super();
                // TODO Auto-generated constructor stub
        }
 
        // Source > Generate Constructor From Fields
        public Issue(int id, String message, String priority) {
                super();
                Id = id;
                this.message = message;
                this.priority = priority;
        }
 
        // Source > Generate Getter and Setter
        public int getId() {
                return Id;
        }
 
        public void setId(int id) {
                Id = id;
        }
 
        public String getMessage() {
                return message;
        }
 
        public void setMessage(String message) {
                this.message = message;
        }
 
        public String getPriority() {
                return priority;
        }
 
        public void setPriority(String priority) {
                this.priority = priority;
        }
 
 
}

N/A

IssueController.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat issues/IssueController.java
package com.issue.tracker.issues;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
 
import javax.persistence.EntityManager;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
@Controller
@RequestMapping
public class IssueController {
 
        Connection conn = null;
 
        @Autowired
        private IssueInterface service;
 
        @Autowired
        EntityManager em;
 
        @GetMapping("/")
        public String index(Model model) {
                List<Issue> issues = service.GetAll();
                model.addAttribute("issuesList", issues);
                return "index";
        }
 
        @GetMapping("/issue/list")
        public String list(Model model) {
                List<Issue> issues = service.GetAll();
                model.addAttribute("issuesList", issues);
                return "issue_index";
        }
 
        @GetMapping("/issue/add")
        public String add(Model model) {
 
                model.addAttribute("issuesForm", new Issue());
                return "issue_form";
        }
        @PostMapping("/issue/save")
        public String save(Issue i, Model model) {
                service.Save(i);
                return "redirect:/issue/list";
        }
 
        @GetMapping("/issue/checkByPriority")
        public String checkByPriority(@RequestParam("priority") String priority, Model model) {
                //
                // Custom code, need to integrate to the JPA
                //
            Properties connectionProps = new Properties();
            connectionProps.put("user", "issue_user");
            connectionProps.put("password", "ManagementInsideOld797");
        try {
                        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/issue_tracker",connectionProps);
                    String query = "SELECT message FROM issue WHERE priority='"+priority+"'";
            System.out.println(query);
                    Statement stmt = conn.createStatement();
                    stmt.executeQuery(query);
 
        } catch (SQLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                }
 
        // TODO: Return the list of the issues with the correct priority
                List<Issue> issues = service.GetAll();
                model.addAttribute("issuesList", issues);
                return "issue_index";
 
        }
 
        @GetMapping("/issue/edit/{id}")
        public String edit(@PathVariable int id, Model model) {
                Optional<Issue> issue = service.GetId(id);
                model.addAttribute("issuesForm",issue);
                return "issue_form";
        }
 
        @GetMapping("/issue/delete/{id}")
        public String delete(@PathVariable int id, Model model) {
                service.Delete(id);
                return "redirect:/issue/list";
        }
}

The file reveals a hidden endpoint, /issue/checkByPriority, that allows listing issues by value supplied to the priority parameter via an SQL query; SELECT message FROM issue WHERE priority='"+priority+"' There is no input sanitization in place for the SQL query, making it vulnerable to SQL injection

IssueInterface.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat issues/IssueInterface.java
package com.issue.tracker.issues;
 
import java.util.List;
import java.util.Optional;
 
public interface IssueInterface {
 
        public List<Issue>GetAll();
        public Optional<Issue>GetId(int id);
        public int Save(Issue i);
        public void Delete(int id);
 
}

N/A

IssueRepository.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat cat issues/IssueRepository.java
package com.issue.tracker.issues;
 
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
 
@Repository
public interface IssueRepository extends CrudRepository<Issue, Integer>{
 
}

N/A

IssueService.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat issues/IssueService.java
package com.issue.tracker.issues;
 
import java.util.List;
import java.util.Optional;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class IssueService implements IssueInterface {
 
        @Autowired
        private IssueRepository data;
 
        @Override
        public List<Issue> GetAll() {
                return (List<Issue>)data.findAll();
        }
 
        @Override
        public Optional<Issue> GetId(int id) {
                return data.findById(id);
        }
 
        @Override
        public int Save(Issue i) {
                int res=0;
                Issue issue = data.save(i);
                if (!issue.equals(null)) {
                        res=1;
                }
 
                return res;
        }
 
        @Override
        public void Delete(int id) {
                data.deleteById(id);
        }
 
}

N/A

users


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ ll users 
total 36K
4.0K -rw-rw-r-- 1 kali kali 3.0K Feb  6  2021 UserController.java
4.0K -rw-rw-r-- 1 kali kali 1.4K Feb  5  2021 Users.java
4.0K -rw-rw-r-- 1 kali kali  248 Feb  5  2021 UsersRepository.java
4.0K -rw-rw-r-- 1 kali kali 1.6K Feb  5  2021 UserDetailsServiceImpl.java
4.0K -rw-rw-r-- 1 kali kali  810 Feb  5  2021 UserService.java
4.0K drwxrwxr-x 2 kali kali 4.0K Feb  5  2021 .
4.0K -rw-rw-r-- 1 kali kali  302 Feb  5  2021 UserInterface.java
4.0K -rw-rw-r-- 1 kali kali  551 Feb  4  2021 Role.java
4.0K drwxr-xr-x 5 kali kali 4.0K Feb  3  2021 ..

Role.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/Role.java
package com.issue.tracker.users;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
 
@Entity
public class Role {
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Id
        private int roleId;
        private String roleName;
 
        public int getRoleId() {
                return roleId;
        }
 
        public void setRoleId(int roleId) {
                this.roleId = roleId;
        }
 
        public String getRoleName() {
                return roleName;
        }
 
        public void setRoleName(String roleName) {
                this.roleName = roleName;
        }
} 

There are roles assigned to users

UserController.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/UserController.java
package com.issue.tracker.users;
 
import java.util.List;
import java.util.Optional;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
@RequestMapping
public class UserController{
 
        @Autowired
        private UsersRepository service;
 
        @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
 
        @GetMapping("/user/list")
        public String list(Model model) {
                List<Users> users = service.findAll();
                model.addAttribute("usersList", users);
                return "user_index";
        }
 
        // --------------------------------------
 
        @GetMapping("/user/add")
        public String add(Model model) {
                model.addAttribute("usersForm", new Users());
                model.addAttribute("formAction", "save");
                return "user_form";
        }
 
        @PostMapping("/user/save")
        public String save(Users i, Model model) {
                String encPass =  bCryptPasswordEncoder.encode(i.getPassword());
                i.setPassword(encPass);
                service.save(i);
                return "redirect:/user/list";
        }
 
        // --------------------------------------
 
        @GetMapping("/user/edit/{id}")
        public String edit(@PathVariable int id, Model model) {
                Optional<Users> user = service.findById(id);
                model.addAttribute("usersForm",user);
                model.addAttribute("formAction", "update");
                return "user_form";
        }
 
        @PostMapping("/user/update")
        public String update(Users i, Model model) {
 
                System.out.println("Boop>" + i.getUserId());
                Users updateUser = service.findById(i.getUserId()).orElse(null);
 
                if (!i.getPassword().isEmpty()) {
                        String encPass =  bCryptPasswordEncoder.encode(i.getPassword());
                        updateUser.setPassword(encPass);
                }
 
                updateUser.setUsername(i.getUsername());
                service.save(updateUser);
                return "redirect:/user/list";
        }
 
        // --------------------------------------
 
        @GetMapping("/user/delete/{id}")
        public String delete(@PathVariable int id) {
                service.deleteById(id);
                return "redirect:/user/list";
        }
 
        // --------------------------------------
 
        @GetMapping("/login")
        public String login(Model model) {
                model.addAttribute("usersForm",new Users());
                return "login";
        }
        @GetMapping("/login-error")
        public String login_error(Model model) {
                model.addAttribute("usersForm",new Users());
                model.addAttribute("loginError",true);
                return "login";
        }
 
        @GetMapping("/register")
        public String register(Model model) {
                model.addAttribute("usersForm", new Users());
                model.addAttribute("formAction", "register");
                return "user_form";
        }
 
        @PostMapping("/user/register")
        public String register_save(Users i, Model model) {
                String encPass =  bCryptPasswordEncoder.encode(i.getPassword());
                i.setPassword(encPass);
                service.save(i);
                return "redirect:/";
        }
}

All enumerataed N/A

UserDetailsServiceImpl.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/UserDetailsServiceImpl.java
package com.issue.tracker.users;
 
 
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
 
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
 
    @Autowired
    private UsersRepository usersRepository;
 
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
 
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
 
        Optional<Users> optionalUser = usersRepository.findByUsername(userName);
 
        if(optionalUser.isPresent()) {
                Users users = optionalUser.get();
 
                List<String> roleList = new ArrayList<String>();
                for(Role role:users.getRoles()) {
                        roleList.add(role.getRoleName());
                }
 
            return User.builder()
                .username(users.getUsername())
                //change here to store encoded password in db
                .password(users.getPassword())
                .roles(roleList.toArray(new String[0]))
                .build();
        } else {
                throw new UsernameNotFoundException("User Name is not Found");
        }
    }
}

N/A

UserInterface.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/UserInterface.java
package com.issue.tracker.users;
 
import java.util.List;
import java.util.Optional;
 
public interface UserInterface {
 
        public List<Users>GetAll();
        public Optional<Users>GetId(int id);
        public int Save(Users i);
        public void Delete(int id);
        public Optional<Users> GetByUsername(String username);
 
}

N/A

UserService.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/UserService.java
package com.issue.tracker.users;
 
import java.util.List;
import java.util.Optional;
 
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class UserService implements UserInterface {
 
        @Autowired
        private UsersRepository data;
 
        @Override
        public List<Users> GetAll() {
                return (List<Users>)data.findAll();
        }
 
        @Override
        public Optional<Users> GetId(int id) {
                return data.findById(id);
        }
 
        @Override
        public int Save(Users i) {
                int res=0;
                Users user = data.save(i);
                if (!user.equals(null)) {
                        res=1;
                }
 
                return res;
        }
 
        @Override
        public void Delete(int id) {
                data.deleteById(id);
        }
 
        @Override
        public Optional<Users> GetByUsername(String username) {
                // TODO Auto-generated method stub
                return null;
        }
 
 
}

N/A

Users.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/Users.java
package com.issue.tracker.users;
 
import java.util.List;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
 
/*
 * Plural name because spring.security has a class called User, and there was a mess overriding both clasess
 */
 
@Entity
@Table(name = "user")
public class Users {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int userId;
        @Column(unique=true)
        private String username;
        private String password;
 
        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "user_role",
                joinColumns = @JoinColumn(name = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "role_id"))
        List<Role> roles;
 
        public int getUserId() {
                return userId;
        }
 
        public void setUserId(int userId) {
                this.userId = userId;
        }
 
        public String getUsername() {
                return username;
        }
 
        public void setUsername(String username) {
                this.username = username;
        }
 
        public String getPassword() {
                return password;
        }
 
        public void setPassword(String password) {
                this.password = password;
        }
 
        public List<Role> getRoles() {
                return roles;
        }
 
        public void setRoles(List<Role> roles) {
                this.roles = roles;
        }
 
}

N/A

UsersRepository.java


┌──(kali㉿kali)-[~/…/java/com/issue/tracker]
└─$ cat users/UsersRepository.java
package com.issue.tracker.users;
 
import java.util.Optional;
 
import org.springframework.data.jpa.repository.JpaRepository;
 
public interface UsersRepository extends JpaRepository<Users, Integer>{
        Optional<Users> findByUsername(String username);
}                                                                                                                       

N/A