Skip to content

Commit

Permalink
Merge branch 'release/0.14.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ljupcovangelski committed Mar 24, 2021
2 parents c787193 + f46de8b commit 9f93bba
Show file tree
Hide file tree
Showing 299 changed files with 6,559 additions and 7,197 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
if: startsWith(github.ref, 'refs/heads/develop')
run: |
aws s3 cp bazel-bin/infrastructure/cli/airy_linux_bin s3://airy-core-binaries/develop/linux/amd64/airy
aws s3 cp bazel-bin/infrastructure/cli/airy_darwin_bin s3://airy-core-binaries/develop/darwin/amd64/airy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.13.0
0.14.0
7 changes: 4 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Airy Bazel tools
git_repository(
name = "com_github_airyhq_bazel_tools",
commit = "b34a57be44e3cdf739e074dde1c3db5b5347cc35",
commit = "3382e1968deebb90f33320b504f7adca3f92c08b",
remote = "https://github.com/airyhq/bazel-tools.git",
shallow_since = "1615392891 +0100",
shallow_since = "1616430778 +0100",
)

load("@com_github_airyhq_bazel_tools//:repositories.bzl", "airy_bazel_tools_dependencies", "airy_jvm_deps")
Expand All @@ -30,6 +30,7 @@ maven_install(
"com.fasterxml.jackson.core:jackson-core:2.10.0",
"com.fasterxml.jackson.core:jackson-databind:2.10.0",
"com.fasterxml.jackson.module:jackson-module-afterburner:2.10.0",
"com.github.everit-org.json-schema:org.everit.json.schema:1.12.2",
"com.google.auth:google-auth-library-oauth2-http:0.20.0",
"com.jayway.jsonpath:json-path:2.4.0",
"com.twilio.sdk:twilio:7.51.0",
Expand Down Expand Up @@ -137,7 +138,7 @@ go_embed_data_dependencies()
go_register_toolchains(
nogo = "@//:airy_nogo",
version = "1.16",
) # my_nogo is in the top-level BUILD file of this workspace
) # airy_nogo is in the top-level BUILD file of this workspace

load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

Expand All @@ -25,12 +24,7 @@ public WebhooksController(Stores stores) {

@PostMapping("/webhooks.subscribe")
public ResponseEntity<?> subscribe(@RequestBody @Valid WebhookSubscriptionPayload payload) {
final String apiSecret = Optional.ofNullable(stores.getWebhook())
.map(Webhook::getApiSecret)
.orElse(UUID.randomUUID().toString());

final Webhook webhook = Webhook.newBuilder()
.setApiSecret(apiSecret)
.setId(UUID.randomUUID().toString())
.setEndpoint(payload.getUrl())
.setStatus(Status.Subscribed)
Expand Down Expand Up @@ -79,7 +73,6 @@ public ResponseEntity<GetWebhookResponse> webhookInfo() {
private GetWebhookResponse fromWebhook(Webhook webhook) {
return GetWebhookResponse.builder()
.headers(webhook.getHeaders())
.apiSecret(webhook.getApiSecret())
.status(webhook.getStatus().toString())
.url(webhook.getEndpoint())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
public class GetWebhookResponse {
private String status;
private String url;
private String apiSecret;
private Map<String, String> headers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,19 @@ public void canManageWebhook() throws Exception {
webTestHelper.post("/webhooks.subscribe", payload, "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.url", equalTo(url)))
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader)))
.andExpect(jsonPath("$.api_secret", is(not(nullValue()))));
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader)));

retryOnException(() -> webTestHelper.post("/webhooks.info", "{}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.url", equalTo(url)))
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader)))
.andExpect(jsonPath("$.api_secret", is(not(nullValue())))),
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader))),
"Webhook was not stored"
);

webTestHelper.post("/webhooks.unsubscribe", payload, "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.url", equalTo(url)))
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader)))
.andExpect(jsonPath("$.api_secret", is(not(nullValue()))));

//TODO add assertion?
.andExpect(jsonPath("$.headers['X-Auth']", equalTo(xAuthHeader)));
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package co.airy.core.api.auth.config;

import co.airy.core.api.auth.dao.InvitationDAO;
import co.airy.core.api.auth.dao.UserDAO;
import co.airy.log.AiryLoggerFactory;
import org.jdbi.v3.core.Jdbi;
Expand Down Expand Up @@ -44,14 +43,8 @@ public void logBeforeExecution(StatementContext context) {
return jdbi;
}

//TODO: BeanFactory to generate bindings for DAOs
@Bean
public UserDAO userDAO(Jdbi jdbi) {
return jdbi.onDemand(UserDAO.class);
}

@Bean
public InvitationDAO invitationDAO(Jdbi jdbi) {
return jdbi.onDemand(InvitationDAO.class);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package co.airy.core.api.auth.controllers;

import co.airy.core.api.auth.controllers.payload.AcceptInvitationRequestPayload;
import co.airy.core.api.auth.controllers.payload.AcceptInvitationResponsePayload;
import co.airy.core.api.auth.controllers.payload.InviteUserRequestPayload;
import co.airy.core.api.auth.controllers.payload.InviteUserResponsePayload;
import co.airy.core.api.auth.controllers.payload.ListResponsePayload;
import co.airy.core.api.auth.controllers.payload.LoginRequestPayload;
import co.airy.core.api.auth.controllers.payload.LoginResponsePayload;
import co.airy.core.api.auth.controllers.payload.PasswordResetRequestPayload;
import co.airy.core.api.auth.controllers.payload.SignupRequestPayload;
import co.airy.core.api.auth.controllers.payload.SignupResponsePayload;
import co.airy.core.api.auth.dao.InvitationDAO;
import co.airy.core.api.auth.controllers.payload.UserPayload;
import co.airy.core.api.auth.dao.UserDAO;
import co.airy.core.api.auth.dto.Invitation;
import co.airy.core.api.auth.dto.User;
import co.airy.core.api.auth.services.Mail;
import co.airy.core.api.auth.services.Password;
Expand All @@ -20,6 +14,7 @@
import co.airy.spring.web.payload.EmptyResponsePayload;
import co.airy.spring.web.payload.RequestErrorResponsePayload;
import org.jdbi.v3.core.statement.UnableToExecuteStatementException;
import org.postgresql.util.PSQLException;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -28,26 +23,26 @@
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.util.stream.Collectors.toList;

@RestController
public class UsersController {
public static final String RESET_PWD_FOR = "reset_pwd_for";
private final InvitationDAO invitationDAO;
private final UserDAO userDAO;
private final Password passwordService;
private final Jwt jwt;
private final Mail mail;
private final ExecutorService executor;

public UsersController(Password passwordService, UserDAO userDAO, InvitationDAO invitationDAO, Jwt jwt, Mail mail) {
public UsersController(Password passwordService, UserDAO userDAO, Jwt jwt, Mail mail) {
this.passwordService = passwordService;
this.userDAO = userDAO;
this.invitationDAO = invitationDAO;
this.jwt = jwt;
this.mail = mail;
executor = Executors.newSingleThreadExecutor();
Expand Down Expand Up @@ -80,11 +75,11 @@ ResponseEntity<?> signupUser(@RequestBody @Valid SignupRequestPayload signupRequ

try {
userDAO.insert(user);
} catch (UnableToExecuteStatementException e) {
} catch (UnableToExecuteStatementException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

return ResponseEntity.ok(SignupResponsePayload.builder()
return ResponseEntity.ok(UserPayload.builder()
.firstName(firstName)
.lastName(lastName)
.token(jwt.tokenFor(userId.toString()))
Expand All @@ -94,7 +89,7 @@ ResponseEntity<?> signupUser(@RequestBody @Valid SignupRequestPayload signupRequ
}

@PostMapping("/users.login")
ResponseEntity<LoginResponsePayload> loginUser(@RequestBody @Valid LoginRequestPayload loginRequestPayload) {
ResponseEntity<UserPayload> loginUser(@RequestBody @Valid LoginRequestPayload loginRequestPayload) {
final String password = loginRequestPayload.getPassword();
final String email = loginRequestPayload.getEmail();

Expand All @@ -104,7 +99,7 @@ ResponseEntity<LoginResponsePayload> loginUser(@RequestBody @Valid LoginRequestP
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

return ResponseEntity.ok(LoginResponsePayload.builder()
return ResponseEntity.ok(UserPayload.builder()
.firstName(user.getFirstName())
.lastName(user.getLastName())
.token(jwt.tokenFor(user.getId().toString()))
Expand Down Expand Up @@ -161,50 +156,23 @@ private String getResetToken(String userId) {
return jwt.tokenFor(userId, refreshClaim);
}

//TODO: Write a custom ExceptionHandler for JDBI
@PostMapping("/users.invite")
ResponseEntity<InviteUserResponsePayload> inviteUser(@RequestBody @Valid InviteUserRequestPayload inviteUserRequestPayload) {
final UUID id = UUID.randomUUID();
final Instant now = Instant.now();

invitationDAO.insert(Invitation.builder()
.id(id)
.acceptedAt(null)
.createdAt(now)
.email(inviteUserRequestPayload.getEmail())
.sentAt(null)
.updatedAt(now)
.createdBy(null)
.build());
return ResponseEntity.status(HttpStatus.CREATED).body(InviteUserResponsePayload.builder()
.id(id)
.build());
}

@PostMapping("/users.accept-invitation")
ResponseEntity<?> acceptInvitation(@RequestBody @Valid AcceptInvitationRequestPayload payload) {
final Invitation invitation = invitationDAO.findById(payload.getId());
@PostMapping("/users.list")
ResponseEntity<ListResponsePayload> listUsers() {
final List<User> users = userDAO.list();

if (!invitationDAO.accept(invitation.getId(), Instant.now())) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new EmptyResponsePayload());
}

final User user = User.builder()
.id(UUID.randomUUID())
.email(invitation.getEmail())
.firstName(payload.getFirstName())
.lastName(payload.getLastName())
.passwordHash(passwordService.hashPassword(payload.getPassword()))
.build();
ListResponsePayload listResponsePayload = new ListResponsePayload();

userDAO.insert(user);
listResponsePayload.setData(users
.stream()
.map(u -> UserPayload.builder()
.firstName(u.getFirstName())
.lastName(u.getLastName())
.token(null)
.id(u.getId().toString())
.build())
.collect(toList()));

return ResponseEntity.ok(AcceptInvitationResponsePayload.builder()
.firstName(user.getFirstName())
.lastName(user.getLastName())
.token(jwt.tokenFor(user.getId().toString()))
.id(user.getId().toString())
.build()
);
return ResponseEntity.ok(listResponsePayload);
}

}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package co.airy.core.api.auth.controllers.payload;

import lombok.Data;

import java.util.List;

@Data
public class ListResponsePayload {
private List<UserPayload> data;
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package co.airy.core.api.auth.controllers.payload;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AcceptInvitationResponsePayload {
@JsonInclude(NON_NULL)
public class UserPayload {
private String id;
private String firstName;
private String lastName;
Expand Down
Loading

0 comments on commit 9f93bba

Please sign in to comment.