//
// Copyright 2010 Cinch Logic Pty Ltd.
//
// http://www.chililog.com
//
// 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.chililog.server.workbench.workers;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.bson.types.ObjectId;
import org.chililog.server.common.ChiliLogException;
import org.chililog.server.common.JsonTranslator;
import org.chililog.server.data.MongoConnection;
import org.chililog.server.data.RepositoryConfigBO;
import org.chililog.server.data.RepositoryConfigController;
import org.chililog.server.data.RepositoryConfigListCriteria;
import org.chililog.server.data.UserBO;
import org.chililog.server.data.UserController;
import org.chililog.server.data.UserListCriteria;
import org.chililog.server.workbench.Strings;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import com.mongodb.DB;
/**
* <p>
* Repository Configuration Worker provides the following API services to define and configure repositories:
* <ul>
* <li>create - HTTP POST /api/repository_info</li>
* <li>read all - HTTP GET /api/repository_info</li>
* <li>read one - HTTP GET /api/repository_info/{id}</li>
* <li>update - HTTP PUT /api/repository_info/{id}</li>
* <li>delete - HTTP DELETE /api/repository_info/{id}</li>
* </p>
* <p>
* Meta information refers to the information that defines a repository - name, parsers, fields, etc.
* </p>
*/
public class RepositoryConfigWorker extends Worker {
public static final String NAME_URI_QUERYSTRING_PARAMETER_NAME = "name";
private static UserBO[] _userListCache = null;
private static Date _userListCacheExpiry = new Date();
/**
* Constructor
*/
public RepositoryConfigWorker(HttpRequest request) {
super(request);
return;
}
/**
* Can only create and delete sessions
*/
@Override
public HttpMethod[] getSupportedMethods() {
return new HttpMethod[] { HttpMethod.POST, HttpMethod.DELETE, HttpMethod.GET, HttpMethod.PUT };
}
/**
* Let's validate if the user is able to access these functions
*/
@Override
protected ApiResult validateAuthenticatedUserRole() {
HttpMethod requestMethod = this.getRequest().getMethod();
try {
UserBO user = this.getAuthenticatedUser();
// Administrators can do it all
if (user.isSystemAdministrator()) {
return new ApiResult();
}
// Cannot POST or DELETE unless system administrator
if (requestMethod == HttpMethod.POST || requestMethod == HttpMethod.DELETE) {
throw new ChiliLogException(Strings.NOT_AUTHORIZED_ERROR);
}
// Do checks for PUT and GET when we execute
return new ApiResult();
} catch (Exception ex) {
return new ApiResult(HttpResponseStatus.UNAUTHORIZED, ex);
}
}
/**
* Create
*
* @throws Exception
*/
@Override
public ApiResult processPost(Object requestContent) throws Exception {
try {
if (requestContent == null) {
throw new ChiliLogException(Strings.REQUIRED_CONTENT_ERROR);
}
RepositoryConfigAO repoConfigAO = JsonTranslator.getInstance().fromJson(
bytesToString((byte[]) requestContent), RepositoryConfigAO.class);
RepositoryConfigBO repoConfigBO = new RepositoryConfigBO();
repoConfigAO.toBO(repoConfigBO);
DB db = MongoConnection.getInstance().getConnection();
RepositoryConfigController.getInstance().save(db, repoConfigBO);
// Return response
return new ApiResult(this.getAuthenticationToken(), JSON_CONTENT_TYPE, new RepositoryConfigAO(repoConfigBO,
getAllUsers(db)));
} catch (Exception ex) {
return new ApiResult(HttpResponseStatus.BAD_REQUEST, ex);
}
}
/**
* Delete
*
* @throws Exception
*/
@Override
public ApiResult processDelete() throws Exception {
try {
String id = this.getUriPathParameters()[ID_URI_PATH_PARAMETER_INDEX];
DB db = MongoConnection.getInstance().getConnection();
RepositoryConfigBO repoConfigBO = RepositoryConfigController.getInstance().tryGet(db, new ObjectId(id));
if (repoConfigBO != null) {
RepositoryConfigController.getInstance().remove(db, repoConfigBO);
}
// Return response
return new ApiResult(this.getAuthenticationToken(), null, null);
} catch (Exception ex) {
return new ApiResult(HttpResponseStatus.BAD_REQUEST, ex);
}
}
/**
* Update
*
* @throws Exception
*/
@Override
public ApiResult processPut(Object requestContent) throws Exception {
try {
if (requestContent == null) {
throw new ChiliLogException(Strings.REQUIRED_CONTENT_ERROR);
}
String id = this.getUriPathParameters()[ID_URI_PATH_PARAMETER_INDEX];
DB db = MongoConnection.getInstance().getConnection();
RepositoryConfigBO repoConfigBO = RepositoryConfigController.getInstance().get(db, new ObjectId(id));
// Only system admin and repo admin for this repo can update details
UserBO user = this.getAuthenticatedUser();
if (!user.isSystemAdministrator() && !user.hasRole(repoConfigBO.getAdministratorRoleName())) {
return new ApiResult(HttpResponseStatus.UNAUTHORIZED, new ChiliLogException(
Strings.NOT_AUTHORIZED_ERROR));
}
RepositoryConfigAO repoConfigAO = JsonTranslator.getInstance().fromJson(
bytesToString((byte[]) requestContent), RepositoryConfigAO.class);
repoConfigAO.toBO(repoConfigBO);
RepositoryConfigController.getInstance().save(db, repoConfigBO);
// Return response
return new ApiResult(this.getAuthenticationToken(), JSON_CONTENT_TYPE, new RepositoryConfigAO(repoConfigBO,
getAllUsers(db)));
} catch (Exception ex) {
return new ApiResult(HttpResponseStatus.BAD_REQUEST, ex);
}
}
/**
* Read
*
* @throws Exception
*/
@Override
public ApiResult processGet() throws Exception {
try {
DB db = MongoConnection.getInstance().getConnection();
Object responseContent = null;
UserBO user = this.getAuthenticatedUser();
if (this.getUriPathParameters() == null || this.getUriPathParameters().length == 0) {
// Get list
RepositoryConfigListCriteria criteria = new RepositoryConfigListCriteria();
this.loadBaseListCriteriaParameters(criteria);
criteria.setNamePattern(this.getUriQueryStringParameter(NAME_URI_QUERYSTRING_PARAMETER_NAME, true));
// if not system admin, limit result to those repo that the user has access
if (!user.isSystemAdministrator()) {
criteria.setNameRestrictions(this.getAuthenticatedUserAllowedRepository());
}
ArrayList<RepositoryConfigBO> boList = RepositoryConfigController.getInstance().getList(db, criteria);
if (!boList.isEmpty()) {
ArrayList<RepositoryConfigAO> aoList = new ArrayList<RepositoryConfigAO>();
for (RepositoryConfigBO repoConfigBO : boList) {
aoList.add(new RepositoryConfigAO(repoConfigBO, getAllUsers(db)));
}
responseContent = aoList.toArray(new RepositoryConfigAO[] {});
ApiResult result = new ApiResult(this.getAuthenticationToken(), JSON_CONTENT_TYPE, responseContent);
if (criteria.getDoPageCount()) {
result.getHeaders().put(PAGE_COUNT_HEADER, new Integer(criteria.getPageCount()).toString());
}
return result;
}
} else {
// Get specific repository - only allowed for system admin and those who have permission
String id = this.getUriPathParameters()[ID_URI_PATH_PARAMETER_INDEX];
RepositoryConfigBO repoConfigBO = RepositoryConfigController.getInstance().get(db, new ObjectId(id));
if (!user.isSystemAdministrator() && !user.hasRole(repoConfigBO.getAdministratorRoleName())
&& !user.hasRole(repoConfigBO.getWorkbenchRoleName())) {
return new ApiResult(HttpResponseStatus.UNAUTHORIZED, new ChiliLogException(
Strings.NOT_AUTHORIZED_ERROR));
}
responseContent = new RepositoryConfigAO(repoConfigBO, getAllUsers(db));
}
// Return response
return new ApiResult(this.getAuthenticationToken(), JSON_CONTENT_TYPE, responseContent);
} catch (Exception ex) {
return new ApiResult(HttpResponseStatus.BAD_REQUEST, ex);
}
}
/**
* <p>
* Get a list of all users so we can figure out which user can access which repository
* </p>
* <p>
* Note that we cache for 30 seconds.
* </p>
*
* @param db
* Database connection
* @return List of all users
* @throws ChiliLogException
*/
private static synchronized UserBO[] getAllUsers(DB db) throws ChiliLogException {
if (_userListCache == null || _userListCacheExpiry.before(new Date())) {
UserListCriteria criteria = new UserListCriteria();
ArrayList<UserBO> list = UserController.getInstance().getList(db, criteria);
_userListCache = list.toArray(new UserBO[] {});
GregorianCalendar cal = new GregorianCalendar();
cal.add(Calendar.SECOND, 10);
_userListCacheExpiry = cal.getTime();
}
return _userListCache;
}
}