Skip to content

Commit

Permalink
Add log4j logging of API requests #499
Browse files Browse the repository at this point in the history
* simplify api request version checking

Conflicts:

	rundeckapp/grails-app/conf/ApiRequestFilters.groovy
  • Loading branch information
gschueler committed Aug 9, 2013
1 parent 67b9a53 commit 7715611
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 34 deletions.
102 changes: 68 additions & 34 deletions rundeckapp/grails-app/conf/ApiRequestFilters.groovy
@@ -1,3 +1,11 @@

import org.apache.log4j.Logger
import org.apache.log4j.MDC
import org.codehaus.groovy.grails.web.util.WebUtils

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/*
* Copyright 2011 DTO Labs, Inc. (http://dtolabs.com)
*
Expand All @@ -14,7 +22,7 @@
* limitations under the License.
*
*/

/*
* ApiRequestFilters.java
*
Expand All @@ -24,18 +32,49 @@
*/

public class ApiRequestFilters {

static final Logger logger = Logger.getLogger('org.rundeck.api.requests')
public static final int V1 = 1
public static final int V2 = 2
public static final int V3 = 3
public static final int V4 = 4
public static final int V5 = 5
public final static int API_EARLIEST_VERSION=V1
public final static int API_CURRENT_VERSION=V5
public final static int API_MIN_VERSION=API_EARLIEST_VERSION
public final static int API_MAX_VERSION=API_CURRENT_VERSION
public static final Map VersionMap = [:]
public static final List Versions = [V1, V2, V3, V4, V5]
static {
Versions.each { VersionMap[it.toString()] = it }
}
public static final Set VersionStrings = new HashSet(VersionMap.values())

def allowed_actions=["renderError","invalid","error"]
public final static int API_EARLIEST_VERSION = V1
public final static int API_CURRENT_VERSION = V5
public final static int API_MIN_VERSION = API_EARLIEST_VERSION
public final static int API_MAX_VERSION = API_CURRENT_VERSION

static def logDetail(HttpServletRequest request, params, String action, String controller, String message = null) {
Map context = [
remoteHost: request.remoteHost,
version: request.api_version ?: '?',
remoteUser:request.remoteUser?: request.authenticatedUser,
valid:!(request.invalidApiAuthentication),
authToken:(request.authenticatedToken?(request.authenticatedToken?.size() > 5 ? request.authenticatedToken.substring(0, 5) :'') + "****":'-'),
controller: controller,
action: action,
params: params,
uri: request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE)?: request.getRequestURI(),
userAgent:request.getHeader('User-Agent')?:'-',
method:request.method,
secure:Boolean.toString(request.isSecure())
]
MDC.clear()
context.each {MDC.put(it.key,it.value?:'')}
try {
logger.info(message ?: context.toString())
} finally {
MDC.clear()
}
}

def allowed_actions = ["renderError", "invalid", "error"]
def filters = {
/**
* Require valid api version in request path /api/version/...
Expand All @@ -46,36 +85,31 @@ public class ApiRequestFilters {
return true
}

if(!params.api_version){
flash.errorCode='api.error.api-version.required'
redirect(controller:'api',action:'renderError')
return false
}
final def reqversion
def unsupported=!(params.api_version==~/^[1-9][0-9]*$/)
if(!unsupported){
try{
reqversion = Integer.parseInt(params.api_version)
if (reqversion < API_MIN_VERSION || reqversion > API_MAX_VERSION) {
unsupported = true
}
}catch (NumberFormatException e){
unsupported=true
}
}
if(unsupported){
render(contentType: "text/xml", encoding: "UTF-8") {
result(error: "true", apiversion: API_CURRENT_VERSION) {
delegate.'error' {
message("Unsupported API Version \"${params.api_version}\". API Request: ${request.forwardURI}. Reason: Current version: ${API_CURRENT_VERSION}")
}
if (!params.api_version) {
flash.errorCode = 'api.error.api-version.required'
redirect(controller: 'api', action: 'renderError')
logDetail(request, params.toString(), actionName, controllerName, 'api.error.api-version.required')
return false
}
def unsupported = !(VersionMap.containsKey(params.api_version))
if (unsupported) {
render(contentType: "text/xml", encoding: "UTF-8") {
result(error: "true", apiversion: API_CURRENT_VERSION) {
delegate.'error' {
message("Unsupported API Version \"${params.api_version}\". API Request: ${request.forwardURI}. Reason: Current version: ${API_CURRENT_VERSION}")
}
}
return false;
}
request.api_version=reqversion
return true
logDetail(request, params.toString(), actionName, controllerName, 'api.error.api-version.unsupported')
return false;
}
request.api_version = VersionMap[params.api_version]
request['ApiRequestFilters.request.parameters']=params.toString()
return true
}
after = {
logDetail(request, request['ApiRequestFilters.request.parameters'], actionName, controllerName)
}
}
}
}
}
2 changes: 2 additions & 0 deletions rundeckapp/grails-app/conf/AuthorizationFilters.groovy
Expand Up @@ -87,6 +87,7 @@ public class AuthorizationFilters {
if (tokenobj && user){
session.user = user.login
request.authenticatedToken=authtoken
request.authenticatedUser=user.login
log.debug("loginCheck found user ${user} via token: ${authtoken}");
def subject = new Subject();
subject.principals << new Username(user.login)
Expand All @@ -103,6 +104,7 @@ public class AuthorizationFilters {
request.invalidAuthToken = "Token:" + (authtoken.size()>5?authtoken.substring(0, 5):'') + "****"
}
request.authenticatedToken = null
request.authenticatedUser = null
request.invalidApiAuthentication = true
if(authtoken){
log.error("Invalid API token used: ${authtoken}");
Expand Down

0 comments on commit 7715611

Please sign in to comment.