Skip to content

Commit

Permalink
Merge pull request #2534 from RestComm/issue-2525
Browse files Browse the repository at this point in the history
Issue 2525
  • Loading branch information
maria-farooq committed Oct 4, 2017
2 parents b7b3a44 + 39afb05 commit 6a657aa
Show file tree
Hide file tree
Showing 13 changed files with 319 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
SELECT * FROM restcomm_accounts WHERE parent_sid=#{parent_sid};
</select>

<select id="getAccountsByOrganization" parameterType="string" resultType="hashmap">
SELECT * FROM restcomm_accounts WHERE organization_sid=#{organization_sid};
</select>

<delete id="removeAccount" parameterType="string">
DELETE FROM restcomm_accounts WHERE sid=#{sid};
</delete>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
SELECT * FROM "restcomm_accounts" WHERE "parent_sid"=#{parent_sid};
</select>

<select id="getAccountsByOrganization" parameterType="string" resultType="hashmap">
SELECT * FROM "restcomm_accounts" WHERE "organization_sid"=#{organization_sid};
</select>

<delete id="removeAccount" parameterType="string">
DELETE FROM "restcomm_accounts" WHERE "sid"=#{sid};
</delete>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

import java.util.List;

import org.restcomm.connect.dao.exceptions.AccountHierarchyDepthCrossed;
import org.restcomm.connect.commons.dao.Sid;
import org.restcomm.connect.dao.entities.Account;
import org.restcomm.connect.dao.exceptions.AccountHierarchyDepthCrossed;

/**
* @author quintana.thomas@gmail.com (Thomas Quintana)
Expand Down Expand Up @@ -106,4 +106,10 @@ public interface AccountsDao {
* @throws AccountHierarchyDepthCrossed
*/
List<String> getAccountLineage(Account account) throws AccountHierarchyDepthCrossed;

/**
* @param sid of organization
* @return
*/
List<Account> getAccountsByOrganization(Sid organizationSid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.net.URI;

import org.joda.time.DateTime;

import org.restcomm.connect.commons.annotations.concurrency.Immutable;
import org.restcomm.connect.commons.dao.Sid;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,6 @@
*/
package org.restcomm.connect.dao.mybatis;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.joda.time.DateTime;
import org.restcomm.connect.dao.exceptions.AccountHierarchyDepthCrossed;
import org.restcomm.connect.commons.annotations.concurrency.ThreadSafe;
import org.restcomm.connect.dao.AccountsDao;
import org.restcomm.connect.dao.entities.Account;
import org.restcomm.connect.commons.dao.Sid;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.restcomm.connect.dao.DaoUtils.readAccountStatus;
import static org.restcomm.connect.dao.DaoUtils.readAccountType;
import static org.restcomm.connect.dao.DaoUtils.readDateTime;
Expand All @@ -46,6 +31,21 @@
import static org.restcomm.connect.dao.DaoUtils.writeSid;
import static org.restcomm.connect.dao.DaoUtils.writeUri;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.joda.time.DateTime;
import org.restcomm.connect.commons.annotations.concurrency.ThreadSafe;
import org.restcomm.connect.commons.dao.Sid;
import org.restcomm.connect.dao.AccountsDao;
import org.restcomm.connect.dao.entities.Account;
import org.restcomm.connect.dao.exceptions.AccountHierarchyDepthCrossed;

/**
* @author quintana.thomas@gmail.com (Thomas Quintana)
* @author maria-farooq@live.com (Maria Farooq)
Expand Down Expand Up @@ -237,6 +237,23 @@ private void updateAccount(final String selector, final Account account) {
}
}

@Override
public List<Account> getAccountsByOrganization(final Sid organizationSid) {
final SqlSession session = sessions.openSession();
try {
final List<Map<String, Object>> results = session.selectList(namespace + "getAccountsByOrganization", organizationSid.toString());
final List<Account> accounts = new ArrayList<Account>();
if (results != null && !results.isEmpty()) {
for (final Map<String, Object> result : results) {
accounts.add(toAccount(result));
}
}
return accounts;
} finally {
session.close();
}
}

private Account toAccount(final Map<String, Object> map) {
final Sid sid = readSid(map.get("sid"));
final DateTime dateCreated = readDateTime(map.get("date_created"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,28 @@
*/
package org.restcomm.connect.http;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.thoughtworks.xstream.XStream;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
import static javax.ws.rs.core.Response.ok;
import static javax.ws.rs.core.Response.status;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.commons.configuration.Configuration;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.joda.time.DateTime;
Expand All @@ -36,6 +54,7 @@
import org.restcomm.connect.dao.entities.AccountList;
import org.restcomm.connect.dao.entities.Client;
import org.restcomm.connect.dao.entities.IncomingPhoneNumber;
import org.restcomm.connect.dao.entities.Organization;
import org.restcomm.connect.dao.entities.RestCommResponse;
import org.restcomm.connect.http.client.rcmlserver.RcmlserverApi;
import org.restcomm.connect.http.client.rcmlserver.RcmlserverNotifications;
Expand All @@ -52,20 +71,10 @@
import org.restcomm.connect.provisioning.number.api.PhoneNumberProvisioningManager;
import org.restcomm.connect.provisioning.number.api.PhoneNumberProvisioningManagerProvider;

import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import static javax.ws.rs.core.MediaType.*;
import static javax.ws.rs.core.Response.Status.*;
import static javax.ws.rs.core.Response.ok;
import static javax.ws.rs.core.Response.status;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import com.thoughtworks.xstream.XStream;

/**
* @author quintana.thomas@gmail.com (Thomas Quintana)
Expand Down Expand Up @@ -114,6 +123,7 @@ private Account createFrom(final Sid accountSid, final MultivaluedMap<String, St

// Issue 108: https://bitbucket.org/telestax/telscale-restcomm/issue/108/account-sid-could-be-a-hash-of-the
final Sid sid = Sid.generate(Sid.Type.ACCOUNT, emailAddress);
Sid organizationSid=null;

String friendlyName = emailAddress;
if (data.containsKey("FriendlyName")) {
Expand All @@ -124,6 +134,19 @@ private Account createFrom(final Sid accountSid, final MultivaluedMap<String, St
if (data.containsKey("Status")) {
status = Account.Status.getValueOf(data.getFirst("Status").toLowerCase());
}
if (data.containsKey("OrganizationSid")) {
Sid orgSid = new Sid(data.getFirst("OrganizationSid"));
// user can add account in same organization
if(!orgSid.equals(parent.getOrganizationSid())){
//only super admin can add account in organizations other than it belongs to
allowOnlySuperAdmin();
if(organizationsDao.getOrganization(orgSid) == null){
throw new IllegalArgumentException("provided OrganizationSid does not exist");
}
organizationSid = orgSid;
}
}
organizationSid = organizationSid != null ? organizationSid : parent.getOrganizationSid();
final String password = data.getFirst("Password");
PasswordValidator validator = PasswordValidatorFactory.createDefault();
if (!validator.isStrongEnough(password))
Expand All @@ -133,7 +156,7 @@ private Account createFrom(final Sid accountSid, final MultivaluedMap<String, St
final StringBuilder buffer = new StringBuilder();
buffer.append("/").append(getApiVersion(null)).append("/Accounts/").append(sid.toString());
final URI uri = URI.create(buffer.toString());
return new Account(sid, now, now, emailAddress, friendlyName, accountSid, type, status, authToken, role, uri, parent.getOrganizationSid());
return new Account(sid, now, now, emailAddress, friendlyName, accountSid, type, status, authToken, role, uri, organizationSid);
}

protected Response getAccount(final String accountSid, final MediaType responseType) {
Expand Down Expand Up @@ -297,7 +320,7 @@ private void removeIncomingPhoneNumbers(Sid accountSid, IncomingPhoneNumbersDao



protected Response getAccounts(final MediaType responseType) {
protected Response getAccounts(final UriInfo info, final MediaType responseType) {
checkAuthenticatedAccount();
//First check if the account has the required permissions in general, this way we can fail fast and avoid expensive DAO operations
checkPermission("RestComm:Read:Accounts");
Expand All @@ -306,8 +329,28 @@ protected Response getAccounts(final MediaType responseType) {
return status(NOT_FOUND).build();
} else {
final List<Account> accounts = new ArrayList<Account>();
// accounts.add(account);
accounts.addAll(accountsDao.getChildAccounts(account.getSid()));

if (info == null) {
accounts.addAll(accountsDao.getChildAccounts(account.getSid()));
} else {
String organizationSid = info.getQueryParameters().getFirst("OrganizationSid");
String domainName = info.getQueryParameters().getFirst("DomainName");

if(organizationSid != null && !(organizationSid.trim().isEmpty())){
allowOnlySuperAdmin();
accounts.addAll(accountsDao.getAccountsByOrganization(new Sid(organizationSid)));
} else if(domainName != null && !(domainName.trim().isEmpty())){
allowOnlySuperAdmin();
Organization organization = organizationsDao.getOrganizationByDomainName(domainName);
if(organization == null){
return status(NOT_FOUND).build();
}
accounts.addAll(accountsDao.getAccountsByOrganization(organization.getSid()));
} else {
accounts.addAll(accountsDao.getChildAccounts(account.getSid()));
}
}

if (APPLICATION_XML_TYPE == responseType) {
final RestCommResponse response = new RestCommResponse(new AccountList(accounts));
return ok(xstream.toXML(response), APPLICATION_XML).build();
Expand Down Expand Up @@ -336,7 +379,9 @@ protected Response putAccount(final MultivaluedMap<String, String> data, final M
Account account = null;
try {
account = createFrom(sid, data, parent);
} catch (final NullPointerException exception) {
} catch (IllegalArgumentException illegalArgumentException) {
return status(BAD_REQUEST).entity(illegalArgumentException.getMessage()).build();
}catch (final NullPointerException exception) {
return status(BAD_REQUEST).entity(exception.getMessage()).build();
} catch (PasswordTooWeak passwordTooWeak) {
return status(BAD_REQUEST).entity(buildErrorResponseBody("Password too weak",responseType)).type(responseType).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
*/
package org.restcomm.connect.http;

import org.restcomm.connect.commons.annotations.concurrency.ThreadSafe;
import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
Expand All @@ -28,11 +29,12 @@
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import org.restcomm.connect.commons.annotations.concurrency.ThreadSafe;

/**
* @author quintana.thomas@gmail.com (Thomas Quintana)
Expand All @@ -58,8 +60,8 @@ public Response optionsAccount(@PathParam("accountSid") final String accountSid)
}

@GET
public Response getAccounts() {
return getAccounts(APPLICATION_JSON_TYPE);
public Response getAccounts(@Context UriInfo info) {
return getAccounts(info, APPLICATION_JSON_TYPE);
}

/* disabled as #1270
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
Expand Down Expand Up @@ -58,8 +60,8 @@ public Response getAccountAsXml(@PathParam("accountSid") final String accountSid
}

@GET
public Response getAccounts() {
return getAccounts(APPLICATION_XML_TYPE);
public Response getAccounts(@Context UriInfo info) {
return getAccounts(info, APPLICATION_XML_TYPE);
}

@Consumes(APPLICATION_FORM_URLENCODED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,9 @@ public List<String> getAccountLineage(Sid accountSid) throws AccountHierarchyDep
public List<String> getAccountLineage(Account account) throws AccountHierarchyDepthCrossed {
throw new NotImplementedException();
}

@Override
public List<Account> getAccountsByOrganization(Sid sid) {
throw new NotImplementedException();
}
}

0 comments on commit 6a657aa

Please sign in to comment.