Skip to content

Commit

Permalink
[Hexlet#159] add table social link and check by id of github
Browse files Browse the repository at this point in the history
  • Loading branch information
d1z3d committed Oct 12, 2024
1 parent c6e49e1 commit 474c3d4
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;

@Component
public class CustomAuthenticationFilter extends OncePerRequestFilter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public class AccountController {

@GetMapping
public String getAccountInfoPage(final Model model, final Authentication authentication) {
System.out.println("customAuth2-: " + authentication.toString());
final var accountInfo = accountService.getInfoAccount(authentication.getName());
final var workspaceInfos = accountService.getWorkspacesInfoListByEmail(accountInfo.email());
model.addAttribute("workspaceRoleInfoList", workspaceInfos);
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/io/hexlet/typoreporter/domain/AccountSocialLink.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.hexlet.typoreporter.domain;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import io.hexlet.typoreporter.domain.account.Account;
import io.hexlet.typoreporter.domain.account.AuthProvider;
import io.hypersistence.utils.hibernate.type.basic.PostgreSQLEnumType;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.hibernate.annotations.Type;

@Getter
@Setter
@ToString
@NoArgsConstructor
@Accessors(chain = true)
@Entity(name = "account_social_links")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class AccountSocialLink implements Identifiable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "social_links_to_accounts_id_seq")
@SequenceGenerator(name = "social_links_to_accounts_id_seq", allocationSize = 15)
private Long id;

@ManyToOne
@JoinColumn(name = "account_id")
@NotNull
private Account account;

@Column(name = "login")
@NotNull
private Integer login;

@NotNull
@Enumerated(EnumType.STRING)
@Column(columnDefinition = "AUTH_PROVIDER")
@Type(PostgreSQLEnumType.class)
private AuthProvider authProvider;
}
16 changes: 16 additions & 0 deletions src/main/java/io/hexlet/typoreporter/domain/account/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import io.hexlet.typoreporter.domain.AbstractAuditingEntity;
import io.hexlet.typoreporter.domain.AccountSocialLink;
import io.hexlet.typoreporter.domain.Identifiable;
import io.hexlet.typoreporter.domain.account.constraint.AccountUsername;
import io.hexlet.typoreporter.domain.typo.Typo;
Expand Down Expand Up @@ -89,6 +90,10 @@ public class Account extends AbstractAuditingEntity implements Identifiable<Long
@ToString.Exclude
private List<Typo> typos = new ArrayList<>();

@OneToMany(mappedBy = "account", cascade = ALL, orphanRemoval = true)
@ToString.Exclude
private List<AccountSocialLink> accountSocialLinks = new ArrayList<>();

public Account addTypo(final Typo typo) {
typos.add(typo);
typo.setAccount(this);
Expand All @@ -112,6 +117,17 @@ public void removeWorkSpaceRole(WorkspaceRole workspaceRole) {
workspaceRole.setAccount(null);
}

public Account addAccountsSocialLinks(AccountSocialLink accountSocialLink) {
accountSocialLink.setAccount(this);
accountSocialLinks.add(accountSocialLink);
return this;
}

public void removeAccountsSocialLinks(AccountSocialLink accountSocialLink) {
accountSocialLinks.remove(accountSocialLink);
accountSocialLink.setAccount(null);
}

@Override
public boolean equals(Object o) {
return this == o || id != null && o instanceof Account other && id.equals(other.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,8 @@ public String getPassword() {
Integer password = oAuth2User.getAttribute("id");
return Objects.requireNonNull(password).toString();
}

public Integer getId() {
return Objects.requireNonNull(oAuth2User.getAttribute("id"));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.hexlet.typoreporter.handler;

import io.hexlet.typoreporter.domain.account.AuthProvider;
import io.hexlet.typoreporter.domain.account.OAuth2GithubUser;
import io.hexlet.typoreporter.repository.AccountRepository;
import io.hexlet.typoreporter.repository.AccountSocialLinkRepository;
import io.hexlet.typoreporter.service.AccountService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -18,6 +20,8 @@ public class OAuth2LoginSuccessHandler extends SavedRequestAwareAuthenticationSu
private AccountService accountService;
@Autowired
private AccountRepository accountRepository;
@Autowired
private AccountSocialLinkRepository accountSocialLinkRepository;

@Override
public void onAuthenticationSuccess(HttpServletRequest request,
Expand All @@ -27,9 +31,11 @@ public void onAuthenticationSuccess(HttpServletRequest request,
OAuth2AuthenticationToken authenticationToken = (OAuth2AuthenticationToken) authentication;
if ("github".equals(authenticationToken.getAuthorizedClientRegistrationId())) {
OAuth2GithubUser user = (OAuth2GithubUser) authentication.getPrincipal();
var isUserExist = accountRepository.existsByEmail(user.getEmail());
if (!isUserExist) {
var accountLink = accountSocialLinkRepository.findAccountSocialLinkByLoginAndAuthProvider(user.getId(), AuthProvider.GITHUB);
if (accountLink.isEmpty()) {
accountService.createGithubUser(user);
} else {
accountService.updateGithubUser(accountLink.get().getAccount(), user);
}
}
response.sendRedirect("/workspaces");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface AccountRepository extends JpaRepository<Account, Long> {

Optional<Account> findAccountByEmail(String email);

Optional<Account> findAccountByUsername(String username);

boolean existsByUsername(String username);
boolean existsByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.hexlet.typoreporter.repository;

import io.hexlet.typoreporter.domain.AccountSocialLink;
import io.hexlet.typoreporter.domain.account.AuthProvider;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface AccountSocialLinkRepository extends JpaRepository<AccountSocialLink, Long> {
Optional<AccountSocialLink> findAccountSocialLinkByLoginAndAuthProvider(Integer login, AuthProvider authProvider);
}
32 changes: 31 additions & 1 deletion src/main/java/io/hexlet/typoreporter/service/AccountService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.hexlet.typoreporter.service;

import io.hexlet.typoreporter.domain.AccountSocialLink;
import io.hexlet.typoreporter.domain.account.Account;
import io.hexlet.typoreporter.domain.account.AuthProvider;
import io.hexlet.typoreporter.domain.account.OAuth2GithubUser;
Expand Down Expand Up @@ -29,6 +30,8 @@
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;

@Service
@Transactional
Expand Down Expand Up @@ -123,7 +126,6 @@ public Account updateProfile(final UpdateProfile updateProfile, final String ema
Account updAccount = accountMapper.toAccount(updateProfile, sourceAccount);
updAccount.setUsername(normalizedUserName);
updAccount.setEmail(normalizedEmail);
System.out.println("12: " + updAccount);
accountRepository.save(updAccount);
return updAccount;
}
Expand Down Expand Up @@ -156,7 +158,35 @@ public void createGithubUser(OAuth2GithubUser user) {
passwordEncoder.encode(user.getPassword()), user.getFirstName(), user.getLastName());
Account account = accountMapper.toAccount(signupAccount);
account.setAuthProvider(AuthProvider.GITHUB);
AccountSocialLink link = new AccountSocialLink();
link.setAccount(account);
link.setLogin(user.getId());
link.setAuthProvider(AuthProvider.GITHUB);
account.addAccountsSocialLinks(link);
accountRepository.save(account);
}

@Transactional
public void updateGithubUser(Account sourceAccount, OAuth2GithubUser user) {
if (isAccountChanged(sourceAccount, user)) {
var accountByEmail = accountRepository.findAccountByEmail(user.getEmail());
var accountByUsername = accountRepository.findAccountByEmail(user.getEmail());
var isNewEmailCanBeUsed = accountByEmail.map(account -> account.equals(sourceAccount)).orElse(true);
var isNewUsernameCanBeUsed = accountByUsername.map(account -> account.equals(sourceAccount)).orElse(true);
if (isNewEmailCanBeUsed && isNewUsernameCanBeUsed) {
sourceAccount.setUsername(user.getLogin());
sourceAccount.setEmail(user.getEmail());
sourceAccount.setFirstName(user.getFirstName());
sourceAccount.setLastName(user.getLastName());
accountRepository.save(sourceAccount);
}
}
}

private boolean isAccountChanged(Account account, OAuth2GithubUser user) {
return !account.getEmail().equalsIgnoreCase(user.getEmail()) ||
!account.getUsername().equalsIgnoreCase(user.getLogin()) ||
!account.getFirstName().equalsIgnoreCase(user.getFirstName()) ||
!account.getLastName().equalsIgnoreCase(user.getLastName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">

<changeSet id="2024-10-06-add-table-social-links-to-accounts" author="d1z3d">
<comment>Таблица для хранения ID пользователя из социальной сети, т.к. пользователя можно идентифицировать только по нему</comment>
<createTable tableName="account_social_links">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="PK_SOCIAL_LINKS_OF_USERS" />
</column>
<column name="account_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="login" type="BIGINT">
<constraints nullable="true" />
</column>
<column name="auth_provider" type="AUTH_PROVIDER">
<constraints nullable="false" />
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="account_id" baseTableName="account_social_links"
constraintName="FK_SOCIAL_LINKS_ON_ACCOUNT" referencedTableName="account"
referencedColumnNames="id" />
<createSequence sequenceName="social_links_to_accounts_id_seq" startValue="1" incrementBy="15" />
</changeSet>
</databaseChangeLog>
2 changes: 2 additions & 0 deletions src/main/resources/db/changelog/db.changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@
relativeToChangelogFile="true" />
<include file="changesets/2024/05/2024-05-31-remove-unique-constraint-to-name-workspace.xml"
relativeToChangelogFile="true" />
<include file="changesets/2024/10/2024-10-06-add-table-social-links-to-accounts.xml"
relativeToChangelogFile="true" />
</databaseChangeLog>

0 comments on commit 474c3d4

Please sign in to comment.