Projekt

Obecné

Profil

« Předchozí | Další » 

Revize deb64a56

Přidáno uživatelem Jakub Danek před více než 5 roky(ů)

re #29 backend implementation of Google OAuth2 authentication

Includes new user registration.

Zobrazit rozdíly:

server/init.sql
12 12
  no_sick_days INT,
13 13
  taken_sick_days INT NOT NULL,
14 14
  alert DATETIME,
15
  token TEXT NOT NULL,
16 15
  email VARCHAR(100) NOT NULL,
17 16
  photo TEXT,
18 17
  creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
......
116 115
-- -----------------------------------------------------
117 116
-- Insert table end_user
118 117
-- -----------------------------------------------------
119
INSERT INTO end_user (first_name, last_name, no_vacations, no_sick_days, taken_sick_days, alert, token, email, photo,
118
INSERT INTO end_user (first_name, last_name, no_vacations, no_sick_days, taken_sick_days, alert, email, photo,
120 119
                      user_role, status)
121
VALUES ('admin', 'admin', 0, NULL, 0, NULL, '', 'testuser@yoso.fi',
120
VALUES ('admin', 'admin', 0, NULL, 0, NULL, 'testuser@yoso.fi',
122 121
        'https://st2.depositphotos.com/9223672/12056/v/950/depositphotos_120568236-stock-illustration-male-face-avatar-logo-template.jpg',
123 122
        'EMPLOYER', 'ACCEPTED');
124 123

  
server/pom.xml
29 29
            <artifactId>spring-boot-starter-security</artifactId>
30 30
        </dependency>
31 31

  
32
        <dependency>
33
            <groupId>org.springframework.security</groupId>
34
            <artifactId>spring-security-oauth2-client</artifactId>
35
        </dependency>
36
        <dependency>
37
            <groupId>org.springframework.security</groupId>
38
            <artifactId>spring-security-oauth2-jose</artifactId>
39
        </dependency>
40

  
32 41
        <dependency>
33 42
            <groupId>org.apache.commons</groupId>
34 43
            <artifactId>commons-lang3</artifactId>
server/src/main/java/org/danekja/ymanager/WebSecurityConfiguration.java
1 1
package org.danekja.ymanager;
2 2

  
3
import org.danekja.ymanager.business.UserManager;
4
import org.danekja.ymanager.business.auth.service.GoogleOidcUserService;
3 5
import org.slf4j.Logger;
4 6
import org.slf4j.LoggerFactory;
7
import org.springframework.beans.factory.annotation.Autowired;
5 8
import org.springframework.context.annotation.Bean;
6 9
import org.springframework.context.annotation.Configuration;
7 10
import org.springframework.security.authentication.AuthenticationProvider;
......
13 16
import org.springframework.security.core.AuthenticationException;
14 17
import org.springframework.security.core.userdetails.UserDetails;
15 18
import org.springframework.security.core.userdetails.UserDetailsService;
19
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
20
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
21
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
16 22

  
17 23
@Configuration
18 24
@EnableWebSecurity
19 25
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
20 26

  
27
    @Autowired
28
    private OAuth2UserService<OidcUserRequest, OidcUser> googleOauthUserService;
29

  
21 30
    @Override
22 31
    protected void configure(HttpSecurity http) throws Exception {
23 32
        http.cors()
......
26 35
                .authorizeRequests()
27 36
                .anyRequest().authenticated()
28 37
                .and()
29
                .httpBasic();
38
                .oauth2Login()
39
                .userInfoEndpoint().oidcUserService(googleOauthUserService);
40
    }
41

  
42
    @Bean
43
    public OAuth2UserService<OidcUserRequest, OidcUser> googleOauthUserService(UserManager userManager) {
44
        return new GoogleOidcUserService(userManager);
30 45
    }
31 46

  
32 47
    /**
server/src/main/java/org/danekja/ymanager/business/UserManager.java
1 1
package org.danekja.ymanager.business;
2 2

  
3
import org.danekja.ymanager.domain.GoogleUser;
3 4
import org.danekja.ymanager.domain.Status;
4 5
import org.danekja.ymanager.domain.User;
5 6
import org.danekja.ymanager.dto.BasicProfileUser;
6 7
import org.danekja.ymanager.ws.rest.exceptions.RESTFullException;
8
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
7 9

  
8 10
import java.util.List;
9 11

  
......
30 32
     * @return found user Object or null
31 33
     */
32 34
    User getUser(Long userId);
35

  
36
    GoogleUser registerUser(OidcIdToken user);
37

  
38
    GoogleUser getUser(OidcIdToken token);
33 39
}
server/src/main/java/org/danekja/ymanager/business/auth/service/GoogleOidcUserService.java
1
package org.danekja.ymanager.business.auth.service;
2

  
3
import org.danekja.ymanager.business.UserManager;
4
import org.danekja.ymanager.domain.GoogleUser;
5
import org.springframework.beans.factory.annotation.Autowired;
6
import org.springframework.beans.factory.annotation.Value;
7
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
8
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
9
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
10
import org.springframework.security.oauth2.core.OAuth2Error;
11
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
12
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
13
import org.springframework.stereotype.Service;
14
import org.springframework.transaction.annotation.Transactional;
15

  
16
import java.util.List;
17

  
18
/**
19
 * Customer {@link OAuth2UserService} of OpenID protocol, which populates user
20
 * object from data stored in database.
21
 * <p>
22
 * If the authenticated user does not have record in database, it is created.
23
 */
24
@Transactional
25
@Service
26
public class GoogleOidcUserService implements OAuth2UserService<OidcUserRequest, OidcUser> {
27

  
28
    private final UserManager userManager;
29

  
30
    @Value("#{'${ymanager.oauth2.client.google.allowed-domains}'.split(',')}")
31
    private List<String> allowedDomains;
32

  
33
    @Autowired
34
    public GoogleOidcUserService(UserManager userManager) {
35
        this.userManager = userManager;
36
    }
37

  
38
    @Override
39
    public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
40
        //this ensures only users from configured domains can log-in
41
        //also, Google allows to configure application as "internal", after that only accounts from your domain
42
        //can sign-in
43
        if (!allowedDomains.isEmpty() && !allowedDomains.contains(userRequest.getIdToken().getClaimAsString("hd"))) {
44
            throw new OAuth2AuthenticationException(new OAuth2Error("403"), "Unauthorized!");
45
        }
46

  
47
        OidcIdToken token = userRequest.getIdToken();
48

  
49
        GoogleUser user = userManager.getUser(userRequest.getIdToken());
50

  
51
        if (user == null) {
52
            user = userManager.registerUser(token);
53
        }
54

  
55
        return user;
56
    }
57
}
server/src/main/java/org/danekja/ymanager/business/impl/DefaultUserManager.java
3 3
import org.danekja.ymanager.business.UserManager;
4 4
import org.danekja.ymanager.business.auth.anot.IsEmployer;
5 5
import org.danekja.ymanager.business.auth.anot.IsOwner;
6
import org.danekja.ymanager.domain.Status;
7
import org.danekja.ymanager.domain.User;
6
import org.danekja.ymanager.domain.*;
8 7
import org.danekja.ymanager.dto.BasicProfileUser;
8
import org.danekja.ymanager.repository.SettingsRepository;
9 9
import org.danekja.ymanager.repository.UserRepository;
10 10
import org.danekja.ymanager.repository.VacationRepository;
11 11
import org.danekja.ymanager.ws.rest.exceptions.RESTFullException;
......
14 14
import org.springframework.beans.factory.annotation.Autowired;
15 15
import org.springframework.dao.DataAccessException;
16 16
import org.springframework.security.core.userdetails.UserDetailsService;
17
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
17 18
import org.springframework.stereotype.Service;
18 19

  
19 20
import java.time.LocalDate;
......
31 32

  
32 33
    private final UserRepository userRepository;
33 34
    private final VacationRepository vacationRepository;
35
    private final SettingsRepository settingsRepository;
34 36

  
35 37
    @Autowired
36
    public DefaultUserManager(UserRepository userRepository, VacationRepository vacationRepository) {
38
    public DefaultUserManager(UserRepository userRepository, VacationRepository vacationRepository, SettingsRepository settingsRepository) {
37 39
        this.userRepository = userRepository;
38 40
        this.vacationRepository = vacationRepository;
41
        this.settingsRepository = settingsRepository;
39 42
    }
40 43

  
41 44
    @Override
......
44 47
        return userRepository.getUser(userId);
45 48
    }
46 49

  
50
    @Override
51
    public GoogleUser getUser(OidcIdToken token) {
52
        //TODO replace with better user object creation after we update the data model - registered and oauth users should be
53
        //TODO in separate tables. We do this here because we need the ID value set
54
        User user = userRepository.getUser(token.getEmail());
55

  
56
        return user != null ? new GoogleUser(user.getId(), user.getUserData(), token) : null;
57
    }
58

  
47 59
    @Override
48 60
    @IsEmployer
49 61
    public List<BasicProfileUser> getUsers(Status status) throws RESTFullException {
......
65 77
        }
66 78
    }
67 79

  
80
    @Override
81
    public GoogleUser registerUser(OidcIdToken token) {
82
        DefaultSettings ds = settingsRepository.get();
83
        //TODO state is Accepted until #45 is resolved
84
        GoogleUser user = new GoogleUser(null, new UserData(ds.getSickDayCount(), ds.getNotification(), UserRole.EMPLOYEE, Status.ACCEPTED), token);
85

  
86
        long id = userRepository.insertUser(user);
87
        UserData data = userRepository.getUserData(id);
88

  
89
        return new GoogleUser(id, data, user.getIdToken());
90
    }
91

  
92

  
68 93
}
server/src/main/java/org/danekja/ymanager/domain/GoogleUser.java
1
package org.danekja.ymanager.domain;
2

  
3
import org.springframework.security.core.GrantedAuthority;
4
import org.springframework.security.core.authority.SimpleGrantedAuthority;
5
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
6
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
7
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
8

  
9
import java.util.Collection;
10
import java.util.Collections;
11
import java.util.Map;
12

  
13
/**
14
 * Represents user authenticated via Google OAuth2 provider
15
 */
16
public class GoogleUser extends User implements OidcUser {
17

  
18
    private static final String HOSTED_DOMAIN = "hd";
19

  
20
    private final OidcIdToken idToken;
21

  
22
    public GoogleUser(Long id, UserData userData, OidcIdToken idToken) {
23
        super(id, userData);
24
        this.idToken = idToken;
25
    }
26

  
27
    public GoogleUser(OidcIdToken idToken) {
28
        this.idToken = idToken;
29
    }
30

  
31
    public String subjectId() {
32
        return idToken.getSubject();
33
    }
34

  
35
    @Override
36
    public String getFirstName() {
37
        return idToken.getGivenName();
38
    }
39

  
40
    @Override
41
    public String getLastName() {
42
        return idToken.getFamilyName();
43
    }
44

  
45
    @Override
46
    public String getEmail() {
47
        return idToken.getEmail();
48
    }
49

  
50
    @Override
51
    public String getPicture() {
52
        return idToken.getPicture();
53
    }
54

  
55
    public String getDomain() {
56
        return idToken.getClaimAsString(HOSTED_DOMAIN);
57
    }
58

  
59
    @Override
60
    public Map<String, Object> getClaims() {
61
        return idToken.getClaims();
62
    }
63

  
64
    @Override
65
    public OidcUserInfo getUserInfo() {
66
        return null;
67
    }
68

  
69
    @Override
70
    public OidcIdToken getIdToken() {
71
        return idToken;
72
    }
73

  
74
    @Override
75
    public Collection<? extends GrantedAuthority> getAuthorities() {
76
        //TODO do not create collection on each call
77
        return Collections.singleton(new SimpleGrantedAuthority(userData.getRole().name()));
78
    }
79

  
80
    @Override
81
    public Map<String, Object> getAttributes() {
82
        return idToken.getClaims();
83
    }
84

  
85
    @Override
86
    public String getName() {
87
        return idToken.getFullName();
88
    }
89
}
server/src/main/java/org/danekja/ymanager/domain/User.java
74 74
     */
75 75
    public abstract String getLastName();
76 76

  
77
    /**
78
     * @return Returns full object with user's data
79
     */
80
    public UserData getUserData() {
81
        return userData;
82
    }
83

  
77 84
    /**
78 85
     * Returns the number of user's remaining hours of an overtime.
79 86
     *
server/src/main/java/org/danekja/ymanager/domain/UserData.java
8 8
    /**
9 9
     * The number of user's remaining hours of an overtime.
10 10
     */
11
    private Float vacationCount;
11
    private Float vacationCount = 0f;
12 12
    /**
13 13
     * The number of user's sick days available during a year.
14 14
     */
15
    private Integer totalSickDayCount;
15
    private Integer totalSickDayCount = 0;
16 16
    /**
17 17
     * The number of user's taken sick days.
18 18
     */
19
    private Integer takenSickDayCount;
19
    private Integer takenSickDayCount = 0;
20 20
    /**
21 21
     * The date and time of sending an email warning about an incoming reset of remaining overtimes and sick days.
22 22
     */
23
    private LocalDateTime notification;
23
    private LocalDateTime notification = null;
24 24
    /**
25 25
     * The user's role.
26 26
     */
27
    private UserRole role;
27
    private UserRole role = null;
28 28
    /**
29 29
     * The user's authorization status.
30 30
     */
31
    private Status status;
31
    private Status status = null;
32 32

  
33 33
    public UserData() {
34 34
    }
35 35

  
36
    public UserData(Integer totalSickDayCount, LocalDateTime notification, UserRole role, Status status) {
37
        this.totalSickDayCount = totalSickDayCount;
38
        this.notification = notification;
39
        this.role = role;
40
        this.status = status;
41
    }
42

  
36 43
    public UserData(Float vacationCount, Integer totalSickDayCount, Integer takenSickDayCount, LocalDateTime notification, UserRole role, Status status) {
37 44
        this.vacationCount = vacationCount;
38 45
        this.totalSickDayCount = totalSickDayCount;
server/src/main/java/org/danekja/ymanager/repository/UserRepository.java
1 1
package org.danekja.ymanager.repository;
2 2

  
3
import org.danekja.ymanager.domain.RegisteredUser;
4
import org.danekja.ymanager.domain.Status;
5
import org.danekja.ymanager.domain.User;
6
import org.danekja.ymanager.domain.UserRole;
3
import org.danekja.ymanager.domain.*;
7 4
import org.danekja.ymanager.dto.BasicProfileUser;
8
import org.danekja.ymanager.dto.DefaultSettings;
9 5
import org.danekja.ymanager.dto.FullUserProfile;
6
import org.danekja.ymanager.repository.jdbc.mappers.UserDataRowMapper;
10 7
import org.danekja.ymanager.repository.jdbc.mappers.UserRowMapper;
11 8
import org.slf4j.Logger;
12 9
import org.slf4j.LoggerFactory;
13 10
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.jdbc.core.JdbcTemplate;
15
import org.springframework.jdbc.core.RowMapper;
16
import org.springframework.jdbc.core.SqlOutParameter;
17
import org.springframework.jdbc.core.SqlParameter;
11
import org.springframework.jdbc.core.*;
12
import org.springframework.jdbc.support.GeneratedKeyHolder;
18 13
import org.springframework.stereotype.Repository;
19 14

  
20 15
import java.sql.*;
21 16
import java.util.ArrayList;
22 17
import java.util.List;
23 18
import java.util.Map;
24
import java.util.Optional;
19
import java.util.Objects;
25 20

  
26 21
import static org.danekja.ymanager.domain.UserRole.getUserRole;
27 22

  
......
31 26
@Repository
32 27
public class UserRepository {
33 28

  
34
    private final RowMapper<RegisteredUser> USER_MAPPER = new UserRowMapper();
29
    private final RowMapper<UserData> USER_DATA_MAPPER = new UserDataRowMapper();
30
    private final RowMapper<RegisteredUser> USER_MAPPER = new UserRowMapper(USER_DATA_MAPPER);
31

  
35 32

  
36 33
    /**
37 34
     * The mapper maps a row from a result of a query to an BasicProfileUser.
......
56 53
        }
57 54
    }
58 55

  
59
    /**
60
     * The mapper maps a row from a result of a query to an BasicProfileUser.
61
     */
62
    private class DefaultSettingsMapper implements RowMapper<DefaultSettings> {
63

  
64
        /**
65
         * Maps a row from a result of a query to an DefaultSettings.
66
         * @param resultSet the row from the result
67
         * @param i the index of the row
68
         * @return the DefaultSettings object
69
         * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set
70
         */
71
        @Override
72
        public DefaultSettings mapRow(ResultSet resultSet, int i) throws SQLException {
73
            final DefaultSettings settings = new DefaultSettings();
74
            settings.setSickDayCount(resultSet.getInt("no_sick_days"));
75
            settings.setNotification(resultSet.getTimestamp("alert").toLocalDateTime());
76
            return settings;
77
        }
78
    }
79

  
80 56
    /**
81 57
     * The logger.
82 58
     */
......
200 176
    }
201 177

  
202 178

  
203
    public Optional<DefaultSettings> getLastDefaultSettings() {
204
        return Optional.ofNullable(this.jdbc.queryForObject("SELECT * FROM default_settings ORDER BY id DESC LIMIT 1", new DefaultSettingsMapper()));
205
    }
206 179

  
207 180
    //---------------------------------- DOMAIN -----------------------------------
208 181

  
......
230 203
        return RepositoryUtils.singleResult(users);
231 204
    }
232 205

  
206
    /**
207
     * Gets user data by user's id
208
     *
209
     * @param id TODO replace by subject Id for google and numeric id for registered (multiple queries)
210
     * @return
211
     */
212
    public UserData getUserData(final long id) {
213
        List<UserData> users = this.jdbc.query("SELECT * FROM end_user WHERE id = ?", USER_DATA_MAPPER, id);
214

  
215
        return RepositoryUtils.singleResult(users);
216
    }
217

  
233 218
    public void updateUser(final User user) {
234 219
        this.jdbc.update("UPDATE end_user SET first_name = ?, last_name = ?, no_vacations = ?, taken_sick_days = ?, email = ?, photo = ?, user_role = ?, status = ? WHERE id = ?",
235 220
                user.getFirstName(), user.getLastName(), user.getVacationCount(), user.getTakenSickDayCount(), user.getEmail(), user.getPhoto(), user.getRole().name(), user.getStatus().name(), user.getId());
236 221
    }
237 222

  
238
    public void insertUser(final User user) {
239
        this.jdbc.update("INSERT INTO end_user (first_name, last_name, no_vacations, no_sick_days, taken_sick_days, alert, email, photo, user_role, status) VALUES (?,?,?,?,?,?,?,?,?,?,?)",
240
                user.getFirstName(), user.getLastName(), user.getVacationCount(), user.getTotalSickDayCount(), user.getTakenSickDayCount(), user.getNotification(), user.getEmail(), user.getPhoto(), user.getRole().name(), user.getStatus().name());
223
    public long insertUser(final User user) {
224
        PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory("INSERT INTO end_user (first_name, last_name, no_vacations, no_sick_days, taken_sick_days, alert, email, photo, user_role, status) VALUES (?,?,?,?,?,?,?,?,?,?)",
225
                Types.VARCHAR,
226
                Types.VARCHAR,
227
                Types.FLOAT,
228
                Types.INTEGER,
229
                Types.INTEGER,
230
                Types.TIMESTAMP,
231
                Types.VARCHAR,
232
                Types.VARCHAR,
233
                Types.VARCHAR,
234
                Types.VARCHAR);
235

  
236

  
237
        factory.setReturnGeneratedKeys(true);
238

  
239
        PreparedStatementCreator stmt = factory.newPreparedStatementCreator(new Object[]{user.getFirstName(), user.getLastName(), user.getVacationCount(), user.getTotalSickDayCount(), user.getTakenSickDayCount(), user.getNotification(), user.getEmail(), user.getPhoto(), user.getRole().name(), user.getStatus().name()});
240

  
241
        GeneratedKeyHolder key = new GeneratedKeyHolder();
242
        this.jdbc.update(stmt, key);
243

  
244
        return Objects.requireNonNull(key.getKey()).longValue();
241 245
    }
242 246

  
243 247
    public void insertSettings(final DefaultSettings settings) {
server/src/main/java/org/danekja/ymanager/repository/jdbc/mappers/UserDataRowMapper.java
1
package org.danekja.ymanager.repository.jdbc.mappers;
2

  
3
import org.danekja.ymanager.domain.Status;
4
import org.danekja.ymanager.domain.UserData;
5
import org.danekja.ymanager.domain.UserRole;
6
import org.springframework.jdbc.core.RowMapper;
7

  
8
import java.sql.ResultSet;
9
import java.sql.SQLException;
10
import java.sql.Timestamp;
11
import java.time.LocalDateTime;
12

  
13
public class UserDataRowMapper implements RowMapper<UserData> {
14

  
15
    @Override
16
    public UserData mapRow(ResultSet resultSet, int rowNum) throws SQLException {
17
        float vacations = resultSet.getFloat("no_vacations");
18
        int sickDays = resultSet.getInt("no_sick_days");
19
        int takenSickDays = resultSet.getInt("taken_sick_days");
20

  
21
        Timestamp date = resultSet.getTimestamp("alert");
22
        LocalDateTime alert = date != null ? ((Timestamp) date).toLocalDateTime() : null;
23

  
24

  
25
        UserRole role = UserRole.valueOf(resultSet.getString("user_role"));
26
        Status status = Status.valueOf(resultSet.getString("status"));
27

  
28
        return new UserData(vacations, sickDays, takenSickDays, alert, role, status);
29
    }
30
}
server/src/main/java/org/danekja/ymanager/repository/jdbc/mappers/UserRowMapper.java
1 1
package org.danekja.ymanager.repository.jdbc.mappers;
2 2

  
3 3
import org.danekja.ymanager.domain.RegisteredUser;
4
import org.danekja.ymanager.domain.Status;
5 4
import org.danekja.ymanager.domain.UserData;
6
import org.danekja.ymanager.domain.UserRole;
7 5
import org.springframework.jdbc.core.RowMapper;
8 6

  
9 7
import java.sql.ResultSet;
......
16 14
 */
17 15
public class UserRowMapper implements RowMapper<RegisteredUser> {
18 16

  
17
    private final RowMapper<UserData> dataRowMapper;
18

  
19
    public UserRowMapper(RowMapper<UserData> dataRowMapper) {
20
        this.dataRowMapper = dataRowMapper;
21
    }
22

  
19 23
    @Override
20 24
    public RegisteredUser mapRow(ResultSet resultSet, int i) throws SQLException {
21 25
        Long id = resultSet.getLong("id");
22 26
        String firstName = resultSet.getString("first_name");
23 27
        String lastName = resultSet.getString("last_name");
24
        float vacations = resultSet.getFloat("no_vacations");
25
        int sickDays = resultSet.getInt("no_sick_days");
26
        int takenSickDays = resultSet.getInt("taken_sick_days");
27

  
28
        Timestamp date = resultSet.getTimestamp("alert");
29
        LocalDateTime alert = date != null ? ((Timestamp) date).toLocalDateTime() : null;
30 28

  
31 29
        String email = resultSet.getString("email");
32 30
        String photo = resultSet.getNString("photo");
33 31

  
34
        date = resultSet.getTimestamp("creation_date");
32
        Timestamp date = resultSet.getTimestamp("creation_date");
35 33
        LocalDateTime creationDate = date.toLocalDateTime();
36
        UserRole role = UserRole.valueOf(resultSet.getString("user_role"));
37
        Status status = Status.valueOf(resultSet.getString("status"));
38 34

  
39
        UserData userData = new UserData(vacations, sickDays, takenSickDays, alert, role, status);
35
        UserData userData = dataRowMapper.mapRow(resultSet, i);
40 36
        return new RegisteredUser(id, firstName, lastName, email, photo, creationDate, userData);
41 37
    }
42 38
}
server/src/main/resources/application.properties
2 2
spring.datasource.url=jdbc:mariadb://db:3306/yamanager
3 3
spring.datasource.username=user
4 4
spring.datasource.password=passwd
5
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
5
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
6
#populate these from your google oauth2 setup
7
#https://www.baeldung.com/spring-security-5-oauth2-login
8
#spring.security.oauth2.client.registration.google.client-id=<client id value here>
9
#spring.security.oauth2.client.registration.google.client-secret=<secret here>
10
#comma-separated list of allowed domains, leave empty for all
11
#ymanager.oauth2.client.google.allowed-domains=domain.com,domain2.com

Také k dispozici: Unified diff