jobList;
61 |
62 | @JsonIgnore
63 | @ManyToOne
64 | private User owner;
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/kraken-client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
25 | React App
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/security/filters/JWTBlacklistFilter.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.security.filters;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.config.Constants;
4 | import com.arcaneiceman.kraken.krakenserver.service.utils.TokenBlacklistService;
5 | import org.springframework.web.filter.GenericFilterBean;
6 |
7 | import javax.servlet.FilterChain;
8 | import javax.servlet.ServletException;
9 | import javax.servlet.ServletRequest;
10 | import javax.servlet.ServletResponse;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.io.IOException;
13 |
14 | /**
15 | * Security Filter : {@link JWTBlacklistFilter}
16 | *
17 | * Filter Order : Second
18 | *
19 | * Checks if the blacklist cache contains the token (token's digest to be more specific)
20 | *
21 | * If it exists:
22 | * Throw {@link HttpServletResponse}.SC_UNAUTHORIZED error
23 | * Else:
24 | * Allow pass through
25 | */
26 | public class JWTBlacklistFilter extends GenericFilterBean {
27 |
28 | private TokenBlacklistService tokenBlacklistService;
29 |
30 | public JWTBlacklistFilter(TokenBlacklistService tokenBlacklistService) {
31 | this.tokenBlacklistService = tokenBlacklistService;
32 | }
33 |
34 | @Override
35 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
36 | throws IOException, ServletException {
37 | String blacklist_digest = (String) servletRequest.getAttribute(Constants.BLACKLIST_DIGEST_KEY);
38 | if (blacklist_digest != null && tokenBlacklistService.isInBlacklist(blacklist_digest))
39 | ((HttpServletResponse) servletResponse).sendError(HttpServletResponse.SC_UNAUTHORIZED, "The token is blocked");
40 | else
41 | filterChain.doFilter(servletRequest, servletResponse);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/config/AsyncConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.context.annotation.PropertySource;
6 | import org.springframework.scheduling.annotation.AsyncConfigurer;
7 | import org.springframework.scheduling.annotation.EnableAsync;
8 | import org.springframework.scheduling.annotation.EnableScheduling;
9 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
10 |
11 | import java.util.concurrent.Executor;
12 |
13 | @Configuration
14 | @EnableAsync
15 | @EnableScheduling
16 | @PropertySource("application.yaml")
17 | public class AsyncConfiguration implements AsyncConfigurer {
18 |
19 | @Value("${application.async.core-pool-size}")
20 | private int corePoolSize;
21 |
22 | @Value("${application.async.max-pool-size}")
23 | private int maxPoolSize;
24 |
25 | @Value("${application.async.queue-capacity}")
26 | private int queueCapacity;
27 |
28 | @Value("${application.async.thread-name}")
29 | private String threadName;
30 |
31 | @Override
32 | public Executor getAsyncExecutor() {
33 | corePoolSize = corePoolSize == 0 ? 5 : corePoolSize;
34 | maxPoolSize = maxPoolSize == 0 ? 5 : maxPoolSize;
35 | queueCapacity = queueCapacity == 0 ? 100 : queueCapacity;
36 | threadName = threadName == null ? "Async Executor Thread" : threadName;
37 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
38 | executor.setCorePoolSize(corePoolSize);
39 | executor.setMaxPoolSize(maxPoolSize);
40 | executor.setQueueCapacity(queueCapacity);
41 | executor.setThreadNamePrefix(threadName);
42 | executor.initialize();
43 | return executor;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/kraken-client/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { BrowserRouter, Route, Switch } from 'react-router-dom'
3 | import Home from './containers/Home/Home'
4 | import Dashboard from './containers/Dashboard/Dashboard'
5 | import Login from './containers/Login/Login'
6 | import Register from './containers/Register/Register'
7 | import Activation from './containers/Activation/Activation'
8 | import ChangePassword from './containers/ChangePassword/ChangePassword'
9 | import ForgotPassword from './containers/ForgotPassword/ForgotPassword'
10 | import Upgrade from './containers/Upgrade/Upgrade';
11 | import Help from './containers/Help/Help'
12 | import { version } from './utils/AppVersion'
13 |
14 | import krakenLogo from './assets/kraken-logo.png';
15 |
16 | class App extends Component {
17 |
18 | componentDidMount(){
19 | document.title = "Kraken Client v" + version
20 | }
21 |
22 | render() {
23 | return (
24 |
25 |
26 |
27 |

28 |
29 |
30 | {/* Secure Routes */}
31 |
32 |
33 | {/* Insecure Routes */}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | );
45 | }
46 |
47 | }
48 |
49 | export default App;
50 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/domain/Job.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.domain;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.domain.abs.TrackedList;
4 | import com.arcaneiceman.kraken.krakenserver.domain.enumerations.TrackingStatus;
5 | import com.fasterxml.jackson.annotation.JsonIgnore;
6 | import lombok.*;
7 | import org.hibernate.annotations.CacheConcurrencyStrategy;
8 | import org.hibernate.annotations.GenericGenerator;
9 |
10 | import javax.persistence.*;
11 | import java.util.Date;
12 | import java.util.List;
13 |
14 | /**
15 | * Created by Wali on 4/21/2018.
16 | */
17 | @EqualsAndHashCode(callSuper = false, of = {"startIndex", "startMarker"})
18 | @Getter
19 | @Setter
20 | @NoArgsConstructor
21 | @AllArgsConstructor
22 | @Embeddable
23 | @Table(name = "jobs")
24 | @Entity
25 | @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
26 | public class Job {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | /**
31 | * Using synthetic key to avoid repeating data
32 | */
33 | @JsonIgnore
34 | @Id
35 | @GeneratedValue(generator = "uuid2")
36 | @GenericGenerator(name = "uuid2", strategy = "uuid2")
37 | private String id;
38 |
39 | // Used by Password Lists and Crunch Lists
40 | @Column
41 | private Long startIndex;
42 |
43 | // Used by Crunch List
44 | @Column
45 | private String startMarker;
46 |
47 | @Column
48 | private Long multiplier;
49 |
50 | @Column
51 | @Enumerated(EnumType.STRING)
52 | private TrackingStatus trackingStatus;
53 |
54 | @Column
55 | private Integer errorCount;
56 |
57 | @Column
58 | private Date willExpireAt;
59 |
60 | @JsonIgnore
61 | @ManyToOne(fetch = FetchType.LAZY)
62 | private Worker worker;
63 |
64 | @JsonIgnore
65 | @ManyToOne(fetch = FetchType.LAZY)
66 | private TrackedList owner;
67 |
68 | @Transient
69 | private List values;
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 |
5 | db:
6 | container_name: postgres
7 | image: postgres
8 | restart: always
9 | environment:
10 | POSTGRES_DB: kraken
11 | POSTGRES_USER: root
12 | POSTGRES_PASSWORD: root
13 | ports:
14 | - "5432:5432"
15 |
16 | s3:
17 | container_name: minio
18 | image: minio/minio
19 | environment:
20 | - MINIO_ROOT_USER=admin
21 | - MINIO_ROOT_PASSWORD=password
22 | ports:
23 | - "9000:9000"
24 | - "9001:9001"
25 | volumes:
26 | - ./kraken-server/s3:/data
27 | command: server /data --console-address ":9001"
28 |
29 | kraken-server:
30 | container_name: server
31 | image: krakendbpc/kraken-server
32 | ports:
33 | - "5000:5000"
34 | command: java
35 | -Dapplication.security.jwt-token-signing-key=password
36 | -Dspring.datasource.url=jdbc:postgresql://db:5432/kraken
37 | -Dspring.datasource.username=root -Dspring.datasource.password=root
38 | -Dfile-storage.url=http://s3:9000
39 | -Dfile-storage.access-key=admin -Dfile-storage.secret-key=password
40 | -Dspring.security.user.password=password
41 | -Dspring.mail.host=url -Dspring.mail.port=0
42 | -Dspring.mail.username=username -Dspring.mail.password=password
43 | -Dapplication.mail.from-address=email -Dapplication.mail.web-url=http://localhost:3000
44 | -Dapplication.recaptcha.secret=secret
45 | -jar kraken-server.jar
46 | depends_on:
47 | - "db"
48 | - "s3"
49 |
50 | kraken-client:
51 | container_name: client
52 | image: krakendbpc/kraken-client
53 | ports:
54 | - "8443:443"
55 | - "8080:80"
56 | depends_on:
57 | - "kraken-server"
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/security/DomainUserDetailsService.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.security;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.domain.User;
4 | import com.arcaneiceman.kraken.krakenserver.repository.UserRepository;
5 | import org.springframework.security.core.GrantedAuthority;
6 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
7 | import org.springframework.security.core.userdetails.UserDetails;
8 | import org.springframework.security.core.userdetails.UserDetailsService;
9 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
10 | import org.springframework.stereotype.Component;
11 | import org.springframework.transaction.annotation.Transactional;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.Locale;
16 |
17 | /**
18 | * Authenticate a user from the database.
19 | */
20 | @Component("userDetailsService")
21 | public class DomainUserDetailsService implements UserDetailsService {
22 |
23 | private final UserRepository userRepository;
24 |
25 | public DomainUserDetailsService(UserRepository userRepository) {
26 | this.userRepository = userRepository;
27 | }
28 |
29 | @Override
30 | @Transactional
31 | public UserDetails loadUserByUsername(final String username) {
32 | User userFromRepository = userRepository.findByUsername(username.toLowerCase(Locale.ENGLISH))
33 | .orElseThrow(() -> new UsernameNotFoundException(""));
34 | return createSpringSecurityUser(userFromRepository);
35 | }
36 |
37 | private org.springframework.security.core.userdetails.User createSpringSecurityUser(User user) {
38 | List grantedAuthorities = new ArrayList<>();
39 | grantedAuthorities.add(new SimpleGrantedAuthority(user.getAuthority()));
40 | return new org.springframework.security.core.userdetails.User(
41 | user.getUsername(), user.getPassword(), grantedAuthorities);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/domain/TrackedCrunchList.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.domain;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.domain.abs.TrackedList;
4 | import com.arcaneiceman.kraken.krakenserver.domain.enumerations.ListType;
5 | import com.arcaneiceman.kraken.krakenserver.domain.enumerations.TrackingStatus;
6 | import io.swagger.annotations.ApiModelProperty;
7 | import lombok.Getter;
8 | import lombok.NoArgsConstructor;
9 | import lombok.Setter;
10 |
11 | import javax.persistence.Column;
12 | import javax.persistence.DiscriminatorValue;
13 | import javax.persistence.Entity;
14 | import java.util.ArrayList;
15 |
16 | @Getter
17 | @Setter
18 | @Entity
19 | @NoArgsConstructor
20 | @DiscriminatorValue(ListType.Constants.CRUNCH_VALUE)
21 | public class TrackedCrunchList extends TrackedList {
22 |
23 | @Column
24 | @ApiModelProperty(hidden = true)
25 | private Integer min;
26 |
27 | @Column
28 | @ApiModelProperty(hidden = true)
29 | private Integer max;
30 |
31 | @Column
32 | @ApiModelProperty(hidden = true)
33 | private String characters;
34 |
35 | @Column
36 | @ApiModelProperty(hidden = true)
37 | private String nextJobString;
38 |
39 | @Column
40 | @ApiModelProperty(hidden = true)
41 | private String pattern;
42 |
43 | public TrackedCrunchList(String listName,
44 | Long totalJobs,
45 | Integer min,
46 | Integer max,
47 | String characters,
48 | String nextJobString,
49 | String pattern,
50 | ActiveRequest owner) {
51 | super(null, listName, ListType.CRUNCH, TrackingStatus.PENDING, totalJobs,
52 | 0L, 0L, 0L, new ArrayList<>(), owner);
53 | this.min = min;
54 | this.max = max;
55 | this.characters = characters;
56 | this.nextJobString = nextJobString;
57 | this.pattern = pattern;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/service/utils/PasswordListJobDelimiterService.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.service.utils;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.domain.PasswordList;
4 | import com.arcaneiceman.kraken.krakenserver.domain.PasswordListJobDelimiter;
5 | import com.arcaneiceman.kraken.krakenserver.repository.PasswordListJobDelimiterRepository;
6 | import com.arcaneiceman.kraken.krakenserver.util.exceptions.SystemException;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.transaction.annotation.Transactional;
9 | import org.zalando.problem.Status;
10 |
11 | @Service
12 | @Transactional
13 | class PasswordListJobDelimiterService {
14 |
15 | private final PasswordListJobDelimiterRepository passwordListJobDelimiterRepository;
16 |
17 |
18 | public PasswordListJobDelimiterService(PasswordListJobDelimiterRepository passwordListJobDelimiterRepository) {
19 | this.passwordListJobDelimiterRepository = passwordListJobDelimiterRepository;
20 | }
21 |
22 | public PasswordListJobDelimiter create(long jobDelimiterIndex,
23 | Long jobStartMarker,
24 | Long jobOffsetMarker,
25 | PasswordList owner) {
26 | PasswordListJobDelimiter passwordListJobDelimiter =
27 | new PasswordListJobDelimiter(null, jobDelimiterIndex, jobStartMarker, jobOffsetMarker, owner);
28 | return passwordListJobDelimiterRepository.save(passwordListJobDelimiter);
29 | }
30 |
31 | public PasswordListJobDelimiter get(Long indexNumber, PasswordList owner) {
32 | return passwordListJobDelimiterRepository.findByIndexNumberAndOwner(indexNumber, owner)
33 | .orElseThrow(() -> new SystemException(2342, "Could not find Job Delimiter", Status.NOT_FOUND));
34 | }
35 |
36 | public void delete(PasswordList owner) {
37 | passwordListJobDelimiterRepository.deleteAll(passwordListJobDelimiterRepository.findByOwner(owner));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/kraken-client/src/components/Toolbar/Toolbar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import Navbar from 'react-bootstrap/Navbar';
4 | import Nav from 'react-bootstrap/Nav'
5 | import Octicon, { LogoGithub, MarkGithub } from '@githubprimer/octicons-react';
6 | import krakenLogo from './../../assets/kraken-logo.png';
7 | import { useHistory } from "react-router-dom";
8 |
9 | import classes from './Toolbar.module.css'
10 |
11 | const Toolbar = (props) => {
12 | // Nav Links
13 | const navLinks = props.navLinks.map(navLink => {
14 | if (navLink.isPrimary)
15 | return ( {navLink.text} )
16 | else
17 | return ( {navLink.text} )
18 | });
19 |
20 | const history = useHistory();
21 | return (
22 |
23 |
{ history.push("/dashboard") }} />
24 |
25 | { history.push("/") }}>Kraken beta
26 |
27 |
29 |
30 |
31 |
32 |
35 |
36 |
37 | );
38 | };
39 |
40 | Toolbar.propTypes = {
41 | navLinks: PropTypes.arrayOf(PropTypes.shape({
42 | text: PropTypes.string.isRequired,
43 | onClick: PropTypes.func.isRequired,
44 | }).isRequired),
45 | type: PropTypes.oneOf(['electron', 'web'])
46 | }
47 |
48 | export default Toolbar;
--------------------------------------------------------------------------------
/kraken-server/src/main/java/com/arcaneiceman/kraken/krakenserver/service/utils/RecaptchaService.java:
--------------------------------------------------------------------------------
1 | package com.arcaneiceman.kraken.krakenserver.service.utils;
2 |
3 | import com.arcaneiceman.kraken.krakenserver.config.RecaptchaConfiguration;
4 | import com.arcaneiceman.kraken.krakenserver.util.exceptions.SystemException;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.stereotype.Service;
9 | import org.zalando.problem.Status;
10 |
11 | import javax.annotation.PostConstruct;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 |
15 | @Service
16 | public class RecaptchaService {
17 |
18 | @Autowired
19 | RecaptchaConfiguration recaptchaConfiguration;
20 |
21 | @PostConstruct
22 | public void verifyVariables() {
23 | if (recaptchaConfiguration == null)
24 | throw new IllegalStateException("Recaptcha Configuration could not be found");
25 | }
26 |
27 | // TODO : Add retry template to this
28 | public void verifyRecaptcha(String recaptchaResponse) {
29 | if (recaptchaConfiguration.getIsInDebug() || !recaptchaConfiguration.isConfigured())
30 | return;
31 | if (recaptchaResponse.isEmpty())
32 | throw new SystemException(231, "Please fill the captcha", Status.BAD_REQUEST);
33 | Map body = new HashMap<>();
34 | body.put("secret", recaptchaConfiguration.getRecaptchaSecret());
35 | body.put("response", recaptchaResponse);
36 | ResponseEntity