Skip to content

Commit

Permalink
Merge branch 'main' of github.com:i-laird/Derivation_Solver
Browse files Browse the repository at this point in the history
  • Loading branch information
i-laird committed Apr 29, 2024
2 parents dbec559 + 2b907fd commit 27ba494
Show file tree
Hide file tree
Showing 48 changed files with 442 additions and 411 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,19 @@ jobs:
# list of changed files within `super-linter`
fetch-depth: 0

- name: Setup Java JDK
uses: actions/setup-java@v3.4.1
with:
distribution: 'corretto'
java-version: '20'

################################
# Run Linter against code base #
################################
- name: Lint Code Base
uses: github/super-linter@v4
env:
VALIDATE_ALL_CODEBASE: false
VALIDATE_JAVA: false
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# stage 1
FROM maven:3.9.1-amazoncorretto-20-debian-bullseye as build

MAINTAINER Ian Laird
LABEL maintainer = "Ian Laird"

WORKDIR /build

Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,22 @@ Download Postman to send test API calls to the service. Open the workspace

## Linting

Proper code format is super important! There is a GitHub action that will fail if the code is not formatted to Google
Java Standard. Luckily it is super easy to check if the code is compliant with the required style for this project.
Proper code format is super important! There is a GitHub action that will fail if the code is not formatted
properly.

```shell
mvn spotless:check
```

If you want an automated way of applying the desired choice execute the following:
You can test Super Linter with the following command.

```shell
mvn spotless:apply
docker run \
-e ACTIONS_RUNNER_DEBUG=true \
-e RUN_LOCAL=true \
-v /path/to/local/codebase:/tmp/lint \
ghcr.io/super-linter/super-linter:latest
```

You can have IntelliJ automatically enforce Google Java Style by following these
[instructions](https://github.com/google/google-java-format/blob/master/README.md#intellij-jre-config).

## Author
[Ian Laird](https://www.linkedin.com/in/ian-laird-b9846198/)

Expand Down
53 changes: 7 additions & 46 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless.maven}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>


</dependencies>

Expand Down Expand Up @@ -179,52 +186,6 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless.maven}</version>
<configuration>
<!-- optional: limit format enforcement to just the files changed by this feature branch -->
<ratchetFrom>origin/main</ratchetFrom>
<formats>
<!-- you can define as many formats as you want, each is independent -->
<format>
<!-- define the files to apply to -->
<includes>
<include>*.md</include>
<include>.gitignore</include>
</includes>
<!-- define the steps to apply to those files -->
<trimTrailingWhitespace/>
<endWithNewline/>
<indent>
<tabs>true</tabs>
<spacesPerTab>4</spacesPerTab>
</indent>
</format>
<format>
<!-- define the files to apply to -->
<includes>
<include>*.yml</include>
</includes>
<!-- define the steps to apply to those files -->
<trimTrailingWhitespace/>
<endWithNewline/>
<indent>
<tabs>true</tabs>
<spacesPerTab>2</spacesPerTab>
</indent>
</format>
</formats>
<!-- define a language-specific format -->
<java>
<googleJavaFormat>
<reflowLongStrings>true</reflowLongStrings>
</googleJavaFormat>
</java>
</configuration>
</plugin>

</plugins>
</build>
</project>
10 changes: 5 additions & 5 deletions src/main/java/calculator/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
@SpringBootApplication
public class Application {

@Bean
PasswordEncoder getEncoder() {
return new BCryptPasswordEncoder();
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// Parser p = new Parser(System.in);
// Term parsedStatement = p.getRoot();
}

@Bean
PasswordEncoder getEncoder() {
return new BCryptPasswordEncoder();
}
}
1 change: 1 addition & 0 deletions src/main/java/calculator/DTO/DerivativeRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;

/** A request for a mathematical expression. */
@Data
@NoArgsConstructor
@AllArgsConstructor
Expand Down
32 changes: 18 additions & 14 deletions src/main/java/calculator/controller/CalculatorController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,52 @@
import calculator.DTO.DerivativeRequest;
import calculator.DTO.DerivativeResponse;
import calculator.service.CalculatorService;
import com.google.common.collect.ImmutableList;
import java.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

/**
Controller handling calculator requests.
*/
/** Controller handling calculator requests. */
@RestController
public final class CalculatorController {

@Autowired private CalculatorService calculatorServiceImpl;

/**
* Health check for the calculator.
*/
/** Health check for the calculator. */
@GetMapping("/health")
@ResponseStatus(HttpStatus.OK)
public String healthCheck() {
return LocalTime.now().toString();
}

/**
* Calculates the anti-derivative of a mathematical expression and then evaluates it at a specific point.
* Calculates the anti-derivative of a mathematical expression and then evaluates it at a specific
* point.
*
* @param request The request.
* @return the anti-derivative and result at a specific point.
*/
@GetMapping(value = "/derivative")
@ResponseStatus(HttpStatus.OK)
public DerivativeResponse generateDerivative(
@RequestBody DerivativeRequest request) {
return calculatorServiceImpl.evaluateDerivative(request.getExpression(), request.getPoints());
public DerivativeResponse generateDerivative(@RequestBody DerivativeRequest request) {
return calculatorServiceImpl.evaluateDerivative(
request.getExpression(), ImmutableList.copyOf(request.getPoints()));
}

/**
* Evaluates a mathematical expression.
*
* @param request the request.
* @return The evaluation of a mathametical expression at specific points.
*/
@GetMapping(value = "/expression")
@ResponseStatus(HttpStatus.OK)
public double generateDerivative(@RequestParam("expression") final String expression) {
return calculatorServiceImpl.evaluateExpression(expression);
public double evaluateExpression(@RequestBody DerivativeRequest request) {
return calculatorServiceImpl.evaluateExpression(
request.getExpression(), ImmutableList.copyOf(request.getPoints()));
}
}
17 changes: 16 additions & 1 deletion src/main/java/calculator/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,36 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/** Controller for user management. */
@RestController
public class UserController {
public final class UserController {

@Autowired private AuthenticationManager authenticationManager;

@Autowired private UserDetailsService userDetailsService;

@Autowired private UserService userService;

/**
* Registers a user.
*
* @param u the user to register.
* @return JWT for the registered user.
* @throws Exception if the user already exists.
*/
@PostMapping("/register")
public ResponseEntity<?> registerUser(@RequestBody @Valid UserGeneration u) throws Exception {
userService.register(u.getEmail(), u.getPassword(), "STANDARD");
return createAuthenticationToken(new JwtRequest(u.getEmail(), u.getPassword()));
}

/**
* Logins in a user.
*
* @param authenticationRequest the users login credentials.
* @return JWT for the logged in user.
* @throws Exception If login fails.
*/
@PostMapping("/authenticate")
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest)
throws Exception {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/calculator/exception/ParseError.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public class ParseError extends RuntimeException {
public ParseError() {
super();
}

public ParseError(String m) {
super(m);
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/calculator/exception/UserNotFound.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public class UserNotFound extends RuntimeException {
public UserNotFound() {
super();
}

public UserNotFound(String m) {
super(m);
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/calculator/security/JwtRequestFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

/** Handles JWT tokens. */
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
public final class JwtRequestFilter extends OncePerRequestFilter {
@Autowired private UserDetailsService jwtUserDetailsService;

@Override
Expand Down Expand Up @@ -48,15 +49,14 @@ protected void doFilterInternal(
// if token is valid configure Spring Security to manually set
// authentication
if (JwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request));
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
chain.doFilter(request, response);
Expand Down
24 changes: 17 additions & 7 deletions src/main/java/calculator/security/JwtTokenUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,39 @@
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

/**
* Util method for JWT tokens.
*/
/** Util method for JWT tokens. */
@Component
public final class JwtTokenUtil implements Serializable {
public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60 * 1000;
private static final long serialVersionUID = 8562677648L;
public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60;

private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS512);

/**
* Gets the username from a JWT.
*
* @param token JWT token.
* @return the username.
*/
public static String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}

/**
* Gets the expiration date for a token.
*
* @param token JWT token.
* @return the expiration date of the token.
*/
public static Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}

/**
* Gets all claims for a token.
*
* @param token JWT token.
* @param claimsResolver claimsResolver
* @return the claims for the token.
*/
public static <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
Expand All @@ -57,8 +64,11 @@ private static Boolean isTokenExpired(String token) {

/**
* Generates a JWT.
*
* @param userDetails the users login credentials.
* @return JWT token.
*/
public static String generateToken(UserDetails userDetails) {
public static String generateToken(final UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername());
}
Expand All @@ -74,7 +84,7 @@ private static String doGenerateToken(Map<String, Object> claims, String subject
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY))
.signWith(SECRET_KEY)
.compact();
}
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/calculator/service/CalculatorService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package calculator.service;

import calculator.DTO.DerivativeResponse;
import java.util.List;
import com.google.common.collect.ImmutableList;

public interface CalculatorService {
DerivativeResponse evaluateDerivative(String expression, List<Integer> evalPoints);

double evaluateExpression(String expression);
DerivativeResponse evaluateDerivative(String expression, ImmutableList<Integer> evalPoints);

double evaluateExpression(String expression, ImmutableList<Integer> evalPoints);
}
Loading

0 comments on commit 27ba494

Please sign in to comment.