Skip to content

Commit

Permalink
HAWKULAR-59 - Invite users. All features, except sending email.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpkrohling committed Oct 2, 2015
1 parent 5e048df commit e7c1c0c
Show file tree
Hide file tree
Showing 17 changed files with 601 additions and 51 deletions.
6 changes: 6 additions & 0 deletions accounts/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.accounts.backend.boundary;

import javax.annotation.security.PermitAll;
import javax.ejb.Stateless;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.validation.constraints.NotNull;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

import org.hawkular.accounts.api.CurrentUser;
import org.hawkular.accounts.api.InvitationService;
import org.hawkular.accounts.api.OrganizationService;
import org.hawkular.accounts.api.RoleService;
import org.hawkular.accounts.api.internal.adapter.HawkularAccounts;
import org.hawkular.accounts.api.model.HawkularUser;
import org.hawkular.accounts.api.model.Invitation;
import org.hawkular.accounts.api.model.Organization;
import org.hawkular.accounts.api.model.OrganizationMembership;
import org.hawkular.accounts.api.model.Role;
import org.hawkular.accounts.backend.control.MsgLogger;
import org.hawkular.accounts.backend.entity.InvitationCreatedEvent;
import org.hawkular.accounts.backend.entity.rest.ErrorResponse;
import org.hawkular.accounts.backend.entity.rest.InvitationAcceptRequest;
import org.hawkular.accounts.backend.entity.rest.InvitationRequest;

/**
* @author Juraci Paixão Kröhling
*/
@Path("/invitations")
@PermitAll
@Stateless
public class InvitationEndpoint {
private static final MsgLogger logger = MsgLogger.LOGGER;
private static final String DEFAULT_ROLE = "Monitor";

@Inject @HawkularAccounts
EntityManager em;

@Inject
RoleService roleService;

@Inject
OrganizationService organizationService;

@Inject
InvitationService invitationService;

@Inject @CurrentUser
HawkularUser user;

@Inject
Event<InvitationCreatedEvent> event;

@POST
public Response inviteUserToOrganization(@NotNull InvitationRequest request) {
Organization organization = organizationService.get(request.getOrganizationId());
Role role = roleService.getByName(DEFAULT_ROLE);

String[] emails = request.getEmails().split("[, ]");
for (String email : emails) {
if (email.isEmpty()) {
continue;
}
Invitation invitation = new Invitation(email, user, organization, role);
em.persist(invitation);
event.fire(new InvitationCreatedEvent(invitation));
}

return Response.noContent().build();
}

@PUT
public Response acceptInvitation(@NotNull InvitationAcceptRequest request) {
Invitation invitation = invitationService.getByToken(request.getToken());

if (null == invitation) {
String message = "The invitation has not been found.";
return Response.status(Response.Status.NOT_FOUND).entity(new ErrorResponse(message)).build();
}

if (user.equals(invitation.getInvitedBy())) {
String message = "The invitation has been created by the same user who is accepting it.";
return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(message)).build();
}

if (invitation.getAcceptedAt() != null) {
String message = "This invitation has already been previously accepted.";

if (!user.equals(invitation.getAcceptedBy())) {
message = "This invitation has already been previously accepted by a different user.";
logger.invitationReused(invitation.getId(), user.getId(), invitation.getAcceptedBy().getId());
}

return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(message)).build();
}

OrganizationMembership membership = new OrganizationMembership(
invitation.getOrganization(),
user,
invitation.getRole());

invitation.setAccepted();
invitation.setAcceptedBy(user);
em.persist(invitation);
em.persist(membership);

return Response.ok(invitation).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.hawkular.accounts.backend.boundary;

import java.util.List;

import javax.annotation.security.PermitAll;
import javax.ejb.Stateless;
import javax.inject.Inject;
Expand Down Expand Up @@ -97,14 +99,8 @@ public class OrganizationEndpoint {
@GET
@Path("/")
public Response getOrganizationsForPersona() {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Organization> query = builder.createQuery(Organization.class);
Root<Organization> root = query.from(Organization.class);
query.select(root);

query.where(builder.equal(root.get(Organization_.owner), persona));

return Response.ok().entity(em.createQuery(query).getResultList()).build();
List<Organization> organizations = organizationService.getOrganizationsForPersona(persona);
return Response.ok().entity(organizations).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,44 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.accounts.api.internal.impl;
package org.hawkular.accounts.backend.control;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.ejb.Asynchronous;
import javax.ejb.Singleton;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.mail.Session;
import javax.persistence.EntityManager;

import org.hawkular.accounts.api.UserService;
import org.hawkular.accounts.api.internal.adapter.HawkularAccounts;
import org.hawkular.accounts.api.model.HawkularUser;
import org.hawkular.accounts.api.model.NameChangedEvent;
import org.hawkular.accounts.api.model.Invitation;
import org.hawkular.accounts.backend.entity.InvitationCreatedEvent;

/**
* @author Juraci Paixão Kröhling
*/
@Singleton
@PermitAll
public class NameChangeObserver {
@Singleton
public class InvitationDispatcher {
MsgLogger logger = MsgLogger.LOGGER;

@Inject
@HawkularAccounts
@Inject @HawkularAccounts
EntityManager em;

@Inject
UserService userService;
@Resource
Session mailSession;

public void dispatchInvitation(@Observes InvitationCreatedEvent event) {
Invitation invitation = event.getInvitation();
if (null == invitation) {
throw new IllegalArgumentException("Invitation event doesn't contain an invitation.");
}

@Asynchronous
public void persistNameChange(@Observes NameChangedEvent event) {
HawkularUser user = userService.getById(event.getUser().getId());
user.setName(event.getUser().getName());
em.persist(user);
invitation = em.merge(invitation);
invitation.setDispatched();
em.persist(invitation);
logger.invitationSubmitted(invitation.getId(), invitation.getToken());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,12 @@ public interface MsgLogger {
@LogMessage(level = Logger.Level.INFO)
@Message(id = 110003, value = "Finished database update")
void infoFinishedDatabaseUpdate();

@LogMessage(level = Logger.Level.INFO)
@Message(id = 110004, value = "Invitation [%s] submitted. Token: [%s]")
void invitationSubmitted(String invitationId, String token);

@LogMessage(level = Logger.Level.WARN)
@Message(id = 110005, value = "Invitation [%s] is being reused by a different user [%s]. It was accepted by: [%s]")
void invitationReused(String invitationId, String userTryingToUse, String acceptedBy);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.accounts.backend.entity;

import org.hawkular.accounts.api.model.Invitation;

/**
* @author Juraci Paixão Kröhling
*/
public class InvitationCreatedEvent {
private Invitation invitation;

public InvitationCreatedEvent(Invitation invitation) {
this.invitation = invitation;
}

public Invitation getInvitation() {
return invitation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.accounts.api.model;
package org.hawkular.accounts.backend.entity.rest;

/**
* CDI event for propagating the change of an user's full name.
*
* @author Juraci Paixão Kröhling
*/
public class NameChangedEvent {

private HawkularUser user;
public class InvitationAcceptRequest {
private String token;

public NameChangedEvent(HawkularUser user) {
this.user = user;
public String getToken() {
return token;
}

public HawkularUser getUser() {
return user;
public void setToken(String token) {
this.token = token;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hawkular.accounts.backend.entity.rest;

/**
* @author Juraci Paixão Kröhling
*/
public class InvitationRequest {
private String organizationId;
private String emails;

public String getOrganizationId() {
return organizationId;
}

public void setOrganizationId(String organizationId) {
this.organizationId = organizationId;
}

public String getEmails() {
return emails;
}

public void setEmails(String emails) {
this.emails = emails;
}
}

0 comments on commit e7c1c0c

Please sign in to comment.