API design with Spring Security, pt. 2
This commit is contained in:
@@ -15,8 +15,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.inMemoryAuthentication()
|
auth.inMemoryAuthentication()
|
||||||
.withUser("Adam").password("test").roles("USER", "ADMIN").and()
|
.withUser("adam@mail.com").password("test").roles("USER", "ADMIN").and()
|
||||||
.withUser("Betty").password("test").roles("USER");
|
.withUser("betty@mail.com").password("test").roles("USER");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ public class User {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
// links to the username in table USERS that is generated by Spring Security
|
||||||
|
private String username;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToMany
|
||||||
@JoinTable(name = "account_user", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "account_id", referencedColumnName = "id"))
|
@JoinTable(name = "account_user", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "account_id", referencedColumnName = "id"))
|
||||||
private List<Account> accounts;
|
private List<Account> accounts;
|
||||||
@@ -35,6 +38,14 @@ public class User {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Account> getAccounts() {
|
public List<Account> getAccounts() {
|
||||||
return accounts;
|
return accounts;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package de.tilman.transactions.repository;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
@@ -12,13 +11,19 @@ import de.tilman.transactions.domain.Account;
|
|||||||
|
|
||||||
public interface AccountRepository extends CrudRepository<Account, Long> {
|
public interface AccountRepository extends CrudRepository<Account, Long> {
|
||||||
|
|
||||||
// http://localhost:8080/accounts/search/findByUserName?username=Betty
|
// http://localhost:8080/accounts/search/findByUserName?username=betty@mail.com
|
||||||
@Query("SELECT a FROM Account a INNER JOIN a.users u WHERE u.name = :username")
|
@Query("SELECT a FROM Account a INNER JOIN a.users u WHERE u.username = :username")
|
||||||
@PreAuthorize("isFullyAuthenticated() && (#username == principal.username)") // http://stackoverflow.com/q/23640487/3761783
|
@PreAuthorize("isFullyAuthenticated() && ((#username == principal.username) || hasRole('ROLE_ADMIN'))") // http://stackoverflow.com/q/23640487/3761783
|
||||||
//@PostFilter("filterObject.user.getId() == principal.id") // http://stackoverflow.com/a/30877376/3761783
|
//@PostFilter("filterObject.user.getId() == principal.id") // http://stackoverflow.com/a/30877376/3761783
|
||||||
List<Account> findByUserName(@Param("username") String username);
|
List<Account> findByUserName(@Param("username") String username);
|
||||||
|
|
||||||
// TODO DELETE auf fremde Accounts möglich?
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
|
@Override
|
||||||
|
Account save(Account account);
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
|
@Override
|
||||||
|
void delete(Account account);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ public interface CategoryRepository extends PagingAndSortingRepository<Category,
|
|||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
Category save(Category user);
|
Category save(Category category);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
void delete(Category user);
|
void delete(Category category);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,15 +1,28 @@
|
|||||||
package de.tilman.transactions.repository;
|
package de.tilman.transactions.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
import de.tilman.transactions.domain.Transaction;
|
import de.tilman.transactions.domain.Transaction;
|
||||||
|
|
||||||
public interface TransactionRepository extends PagingAndSortingRepository<Transaction, Long> {
|
public interface TransactionRepository extends PagingAndSortingRepository<Transaction, Long> {
|
||||||
|
|
||||||
|
// TODO How to prevent loading transactions from other user's accounts?
|
||||||
|
// --> Solution? http://stackoverflow.com/a/21577081/3761783
|
||||||
|
@PreAuthorize("isFullyAuthenticated() && (#username == principal.username)")
|
||||||
|
@Query("SELECT t FROM Transaction t INNER JOIN t.account a WHERE a.id = :accountId AND t.description like :prefix%")
|
||||||
|
List<Transaction> getDescriptions(@Param("accountId") Long accountId, @Param("prefix") String prefix);
|
||||||
|
|
||||||
|
List<Transaction> findFirst10ByAccountIdOrderByDateDesc(@Param("accountId") Long accountId);
|
||||||
|
|
||||||
@RestResource(exported = false)
|
@RestResource(exported = false)
|
||||||
@Override
|
Page<Transaction> findAll(Pageable pageable);
|
||||||
Page<Transaction> findAll();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,19 @@ package de.tilman.transactions.repository;
|
|||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
import de.tilman.transactions.domain.User;
|
import de.tilman.transactions.domain.User;
|
||||||
|
|
||||||
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
|
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
|
||||||
|
|
||||||
|
@PreAuthorize("isFullyAuthenticated() && ((#username == principal.username) || hasRole('ROLE_ADMIN'))")
|
||||||
|
@Query("SELECT u FROM User u WHERE u.username = :username")
|
||||||
|
User getByUsername(@Param("username") String username);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
User save(User user);
|
User save(User user);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
INSERT INTO User (id, name) VALUES (1, 'Adam'), (2, 'Betty');
|
INSERT INTO User (id, name, username) VALUES (1, 'Adam', 'adam@mail.com'), (2, 'Betty', 'betty@mail.com');
|
||||||
INSERT INTO Account (id, name, owner_id) VALUES (1, 'Gemeinschaftskonto', 1), (2, 'Konto Adam', 1);
|
INSERT INTO Account (id, name, owner_id) VALUES (1, 'Gemeinschaftskonto', 1), (2, 'Konto Adam', 1);
|
||||||
|
|
||||||
INSERT INTO Category (id, name, account_id, position) VALUES (1, 'Essen - Lebensmittel', 1, 2), (2, 'Einnahmen - Gehalt', 1, 1), (3, 'Essen - Arbeit', 1, 3), (4, 'Einnahmen - Gehalt', 2, 1), (5, 'Technik - Server und Hosting', 2, 2);
|
INSERT INTO Category (id, name, account_id, position) VALUES (1, 'Essen - Lebensmittel', 1, 2), (2, 'Einnahmen - Gehalt', 1, 1), (3, 'Essen - Arbeit', 1, 3), (4, 'Einnahmen - Gehalt', 2, 1), (5, 'Technik - Server und Hosting', 2, 2);
|
||||||
@@ -6,7 +6,7 @@ INSERT INTO Category (id, name, account_id, position) VALUES (1, 'Essen - Lebens
|
|||||||
|
|
||||||
INSERT INTO Account_User (account_id, user_id) VALUES (1, 1), (1, 2), (2, 1);
|
INSERT INTO Account_User (account_id, user_id) VALUES (1, 1), (1, 2), (2, 1);
|
||||||
|
|
||||||
/*
|
|
||||||
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES
|
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES
|
||||||
(NULL, 1280.81, 1, 1, '2014-06-01', 'Gehalt', null),
|
(NULL, 1280.81, 1, 1, '2014-06-01', 'Gehalt', null),
|
||||||
(NULL, -2.21, 1, 2, '2014-06-10', 'Brot', null),
|
(NULL, -2.21, 1, 2, '2014-06-10', 'Brot', null),
|
||||||
@@ -28,4 +28,3 @@ INSERT INTO Transaction (id, amount, account_id, category_id, date, description,
|
|||||||
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, -1.50, 1, 2, CURRENT_TIMESTAMP(), 'Transaction', null); Commit;
|
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, -1.50, 1, 2, CURRENT_TIMESTAMP(), 'Transaction', null); Commit;
|
||||||
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, -1.50, 1, 3, CURRENT_TIMESTAMP(), 'Transaction', null); Commit;
|
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, -1.50, 1, 3, CURRENT_TIMESTAMP(), 'Transaction', null); Commit;
|
||||||
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, 1.50, 1, 4, CURRENT_TIMESTAMP()+1, 'LAST Transaction', null); Commit;
|
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES (NULL, 1.50, 1, 4, CURRENT_TIMESTAMP()+1, 'LAST Transaction', null); Commit;
|
||||||
*/
|
|
||||||
Reference in New Issue
Block a user