Skip to content

Commit

Permalink
✨ : teams & users mgmt
Browse files Browse the repository at this point in the history
  • Loading branch information
juwit committed Aug 6, 2019
1 parent 1ab94a0 commit bc0ad79
Show file tree
Hide file tree
Showing 36 changed files with 1,083 additions and 85 deletions.
4 changes: 0 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/io/codeka/gaia/bo/Stack.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.codeka.gaia.bo;

import io.codeka.gaia.bo.backend.Backend;
import io.codeka.gaia.teams.bo.Team;
import org.springframework.data.mongodb.core.mapping.DBRef;

import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -45,6 +46,9 @@ public class Stack {

private StackState state = StackState.NEW;

@DBRef
private Team ownerTeam;

public String getId() {
return id;
}
Expand Down Expand Up @@ -100,4 +104,9 @@ public StackState getState() {
public void setState(StackState state) {
this.state = state;
}
}

public void setOwnerTeam(Team ownerTeam) {
this.ownerTeam = ownerTeam;
}

}
23 changes: 22 additions & 1 deletion src/main/java/io/codeka/gaia/bo/TerraformModule.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.codeka.gaia.bo;

import io.codeka.gaia.teams.bo.Team;
import io.codeka.gaia.teams.bo.User;
import org.springframework.data.mongodb.core.mapping.DBRef;

import java.util.ArrayList;
import java.util.List;

public class TerraformModule {
Expand All @@ -12,12 +17,17 @@ public class TerraformModule {

private String directory;

private List<TerraformVariable> variables;
private List<TerraformVariable> variables = new ArrayList<>();

private String name;

private String description;

private String cliVersion;

@DBRef
private List<Team> authorizedTeams = new ArrayList<>();

public String getId() {
return id;
}
Expand Down Expand Up @@ -82,4 +92,15 @@ public void setCliVersion(String cliVersion) {
this.cliVersion = cliVersion;
}

public List<Team> getAuthorizedTeams() {
return authorizedTeams;
}

public void setAuthorizedTeams(List<Team> authorizedTeams) {
this.authorizedTeams = authorizedTeams;
}

public boolean isAuthorizedFor(User user) {
return user.isAdmin() || this.authorizedTeams.contains(user.getTeam());
}
}
23 changes: 0 additions & 23 deletions src/main/java/io/codeka/gaia/config/RepositoryConfig.java

This file was deleted.

18 changes: 13 additions & 5 deletions src/main/java/io/codeka/gaia/controller/IndexController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import io.codeka.gaia.bo.StackState;
import io.codeka.gaia.repository.StackRepository;
import io.codeka.gaia.repository.TerraformModuleRepository;
import io.codeka.gaia.teams.bo.Team;
import io.codeka.gaia.teams.bo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -20,11 +22,17 @@ public IndexController(TerraformModuleRepository moduleRepository, StackReposito
}

@GetMapping("/")
public String index(Model model){
model.addAttribute("moduleCount", this.moduleRepository.count());

model.addAttribute("runningStackCount", stackRepository.countStacksByState(StackState.RUNNING));
model.addAttribute("toUpdateStackCount", stackRepository.countStacksByState(StackState.TO_UPDATE));
public String index(Model model, User user, Team userTeam){
if(user.isAdmin()){
model.addAttribute("moduleCount", this.moduleRepository.count());
model.addAttribute("runningStackCount", this.stackRepository.countStacksByState(StackState.RUNNING));
model.addAttribute("toUpdateStackCount", this.stackRepository.countStacksByState(StackState.TO_UPDATE));
}
else{
model.addAttribute("moduleCount", this.moduleRepository.countByAuthorizedTeamsContaining(userTeam));
model.addAttribute("runningStackCount", stackRepository.countStacksByStateAndOwnerTeam(StackState.RUNNING, userTeam));
model.addAttribute("toUpdateStackCount", stackRepository.countStacksByStateAndOwnerTeam(StackState.TO_UPDATE, userTeam));
}

return "index";
}
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/io/codeka/gaia/controller/JobRestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.codeka.gaia.controller;

import io.codeka.gaia.bo.Job;
import io.codeka.gaia.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/jobs")
public class JobRestController {

private JobRepository jobRepository;

@Autowired
public JobRestController(JobRepository jobRepository) {
this.jobRepository = jobRepository;
}

@GetMapping(params = "stackId")
public List<Job> jobs(@RequestParam String stackId){
return this.jobRepository.findAllByStackId(stackId);
}

@GetMapping("/{id}")
public Job job(@PathVariable String id){
return this.jobRepository.findById(id).orElseThrow(JobNotFoundException::new);
}

}

@ResponseStatus(HttpStatus.NOT_FOUND)
class JobNotFoundException extends RuntimeException{
}
48 changes: 48 additions & 0 deletions src/main/java/io/codeka/gaia/controller/ModuleRestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.codeka.gaia.controller;

import io.codeka.gaia.bo.TerraformModule;
import io.codeka.gaia.repository.TerraformModuleRepository;
import io.codeka.gaia.teams.bo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
* Rest controller for the module API
*/
@RestController
@RequestMapping("/api/modules")
public class ModuleRestController {

private TerraformModuleRepository moduleRepository;

@Autowired
public ModuleRestController(TerraformModuleRepository moduleRepository) {
this.moduleRepository = moduleRepository;
}

@GetMapping("")
public List<TerraformModule> findAllModules(User user){
if(user.isAdmin()){
return moduleRepository.findAll();
}
return moduleRepository.findAllByAuthorizedTeamsContaining(user.getTeam());
}

@GetMapping("/{id}")
public TerraformModule findModule(@PathVariable String id, User user){
if(user.isAdmin()){
return moduleRepository.findById(id).orElseThrow(ModuleNotFoundException::new);
}
return moduleRepository.findByIdAndAuthorizedTeamsContaining(id, user.getTeam()).orElseThrow(ModuleNotFoundException::new);
}

@Secured("ROLE_ADMIN")
@PutMapping("/{id}")
public TerraformModule saveModule(@PathVariable String id, @RequestBody TerraformModule module){
return moduleRepository.save(module);
}

}
57 changes: 57 additions & 0 deletions src/main/java/io/codeka/gaia/controller/StackRestController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.codeka.gaia.controller;

import io.codeka.gaia.bo.Stack;
import io.codeka.gaia.repository.StackRepository;
import io.codeka.gaia.teams.bo.Team;
import io.codeka.gaia.teams.bo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/stacks")
public class StackRestController {

private StackRepository stackRepository;

@Autowired
public StackRestController(StackRepository stackRepository) {
this.stackRepository = stackRepository;
}

@GetMapping
public List<Stack> listStacks(User user){
if(user.isAdmin()){
return stackRepository.findAll();
}
return stackRepository.findByOwnerTeam(user.getTeam());
}

@GetMapping("/{id}")
public Stack getStack(@PathVariable String id, User user){
if(user.isAdmin()){
return stackRepository.findById(id).orElseThrow(StackNotFoundException::new);
}
return stackRepository.findByIdAndOwnerTeam(id, user.getTeam()).orElseThrow(StackNotFoundException::new);
}

@PostMapping()
public Stack save(@RequestBody Stack stack, Team userTeam){
stack.setOwnerTeam(userTeam);
stack.setId(UUID.randomUUID().toString());
return stackRepository.save(stack);
}

@PutMapping("/{id}")
public Stack update(@PathVariable String id, @RequestBody Stack stack){
return stackRepository.save(stack);
}

}

@ResponseStatus(HttpStatus.NOT_FOUND)
class StackNotFoundException extends RuntimeException {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import io.codeka.gaia.bo.TerraformModule;
import io.codeka.gaia.repository.TerraformModuleGitRepository;
import io.codeka.gaia.repository.TerraformModuleRepository;
import io.codeka.gaia.teams.bo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
Expand All @@ -28,24 +30,32 @@ public TerraformModuleController(
}

@GetMapping("/modules")
public String modulesList(Model model){
model.addAttribute("modules", terraformModuleRepository.findAll());
public String modulesList(Model model, User user){
if(user.isAdmin()){
model.addAttribute("modules", terraformModuleRepository.findAll());
}
else{
model.addAttribute("modules", terraformModuleRepository.findAllByAuthorizedTeamsContaining(user.getTeam()));
}

return "modules";
}

@Secured("ROLE_ADMIN")
@GetMapping("/modules/{id}")
public String module(@PathVariable String id, Model model){
model.addAttribute("module", terraformModuleRepository.findById(id).orElseThrow());
public String module(@PathVariable String id, Model model, User user){
var module = terraformModuleRepository.findById(id).orElseThrow(ModuleNotFoundException::new);
if(!module.isAuthorizedFor(user)){
throw new ModuleForbiddenException();
}
model.addAttribute("module", module);
return "module";
}

@Secured("ROLE_ADMIN")
@PostMapping("/modules/{id}")
public String saveModule(@ModelAttribute TerraformModule module, Model model){
public String saveModule(@ModelAttribute TerraformModule module, Model model, User user){
terraformModuleRepository.save(module);
return modulesList(model);
return modulesList(model, user);
}

@GetMapping("/modules/{id}/description")
Expand All @@ -63,3 +73,11 @@ public Optional<String> readme(@PathVariable String id) {
}

}

@ResponseStatus(HttpStatus.NOT_FOUND)
class ModuleNotFoundException extends RuntimeException{
}

@ResponseStatus(HttpStatus.FORBIDDEN)
class ModuleForbiddenException extends RuntimeException{
}
4 changes: 2 additions & 2 deletions src/main/java/io/codeka/gaia/repository/JobRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import io.codeka.gaia.bo.Job;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* Repository for jobs
*/
@RepositoryRestResource
@Repository
public interface JobRepository extends MongoRepository<Job, String>{

List<Job> findAllByStackId(String stackId);
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/io/codeka/gaia/repository/StackRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@

import io.codeka.gaia.bo.Stack;
import io.codeka.gaia.bo.StackState;
import io.codeka.gaia.teams.bo.Team;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.stereotype.Repository;

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

/**
* Repository for stacks
* Repository interface for stacks
*/
@RepositoryRestResource
@Repository
public interface StackRepository extends MongoRepository<Stack, String>{

int countStacksByStateAndOwnerTeam(StackState state, Team team);

int countStacksByState(StackState state);

List<Stack> findByOwnerTeam(Team team);

Optional<Stack> findByIdAndOwnerTeam(String id, Team team);
}

0 comments on commit bc0ad79

Please sign in to comment.