Skip to content

Commit

Permalink
Collect timing stats for evaluating an authorization decision.
Browse files Browse the repository at this point in the history
  • Loading branch information
noahcampbell authored and gschueler committed Nov 19, 2010
1 parent 11366b4 commit cf0ad7d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 11 deletions.
Expand Up @@ -36,6 +36,13 @@ public interface Decision {
*/
Explanation explain();

/**
* Decision evaluation time.
*
* @return evaluationTime The number of milliseconds it took to render this decision.
*/
long evaluationDuration();

/**
* Return the time in seconds since the cache was last refreshed.
* @return seconds
Expand Down
Expand Up @@ -114,6 +114,12 @@ public void describe(PrintStream out) {
out.println("No authorization attempted.");
}
};
}


@Override
public long evaluationDuration() {
return 0;
}};
}

Expand Down Expand Up @@ -161,6 +167,12 @@ public Code getCode() {
return Code.GRANTED_NO_AUTHORIZATION_ATTEMPTED;
}
};
}


@Override
public long evaluationDuration() {
return 0;
}});
}
}
Expand Down
Expand Up @@ -84,6 +84,8 @@ public SAREAuthorization() throws IOException, PoliciesParseException {
private Decision internalEvaluate(Map<String, String> resource, Subject subject, String action,
Set<Attribute> environment) {

long start = System.currentTimeMillis();

if(resource == null) {
throw new IllegalArgumentException("Resource does not identify any resource because it's an empty resource property or null.");
} else {
Expand All @@ -99,7 +101,7 @@ private Decision internalEvaluate(Map<String, String> resource, Subject subject,

if(subject == null) throw new IllegalArgumentException("Invalid subject, subject is null.");
if(action == null || action.length() <= 0) {
return authorize(false, "No action provided.", Code.REJECTED_NO_ACTION_PROVIDED, resource, subject, action, environment);
return authorize(false, "No action provided.", Code.REJECTED_NO_ACTION_PROVIDED, resource, subject, action, environment, System.currentTimeMillis() - start);
}
// environment can be null.
if(environment == null) {
Expand All @@ -110,22 +112,22 @@ private Decision internalEvaluate(Map<String, String> resource, Subject subject,

List<Context> contexts = policies.narrowContext(subject, environment);
if(contexts.size() <= 0) {
return authorize(false, "No context matches subject or environment", Code.REJECTED_NO_SUBJECT_OR_ENV_FOUND, resource, subject, action, environment);
return authorize(false, "No context matches subject or environment", Code.REJECTED_NO_SUBJECT_OR_ENV_FOUND, resource, subject, action, environment, System.currentTimeMillis() - start);
}

ContextDecision contextDecision = null;
for(Context ctx : contexts) {
contextDecision = ctx.includes(resource, action);
if(contextDecision.granted()) {
return authorize(true, contextDecision, resource, subject, action, environment);
return createAuthorize(true, contextDecision, resource, subject, action, environment, System.currentTimeMillis() - start);
}
}

if(contextDecision == null) {
return authorize(false, "No resource or action matched.",
Code.REJECTED_NO_RESOURCE_OR_ACTION_MATCH, resource, subject, action, environment);
Code.REJECTED_NO_RESOURCE_OR_ACTION_MATCH, resource, subject, action, environment, System.currentTimeMillis() - start);
} else {
return authorize(false, contextDecision, resource, subject, action, environment);
return createAuthorize(false, contextDecision, resource, subject, action, environment, System.currentTimeMillis() - start);
}
}

Expand All @@ -137,7 +139,7 @@ public Decision evaluate(Map<String, String> resource, Subject subject,

Decision decision = internalEvaluate(resource, subject, action, environment);
StringBuilder sb = new StringBuilder();
sb.append("Evaluating ").append(decision).append(':');
sb.append("Evaluating ").append(decision).append(" (").append(decision.evaluationDuration()).append("ms)").append(':');

ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream pw = new PrintStream(out, true);
Expand Down Expand Up @@ -165,8 +167,8 @@ public Set<Decision> evaluate(Set<Map<String, String>> resources, Subject subjec

private static Decision authorize(final boolean authorized, final String reason,
final Code reasonId, final Map<String, String> resource, final Subject subject,
final String action, final Set<Attribute> environment) {
return authorize(authorized, new Explanation() {
final String action, final Set<Attribute> environment, final long evaluationTime) {
return createAuthorize(authorized, new Explanation() {

public Code getCode() {
return reasonId;
Expand All @@ -179,12 +181,12 @@ public void describe(PrintStream out) {
public String toString() {
return "\t" + reason + " => " + reasonId;
}
}, resource, subject, action, environment);
}, resource, subject, action, environment, evaluationTime);
}

private static Decision authorize(final boolean authorized, final Explanation explanation,
private static Decision createAuthorize(final boolean authorized, final Explanation explanation,
final Map<String, String> resource, final Subject subject,
final String action, final Set<Attribute> environment) {
final String action, final Set<Attribute> environment, final long evaluationTime) {

return new Decision(){
private String representation;
Expand Down Expand Up @@ -240,6 +242,10 @@ public String toString() {
public Explanation explain() {
return explanation;
}
@Override
public long evaluationDuration() {
return evaluationTime;
}
};
}

Expand Down
2 changes: 2 additions & 0 deletions rundeckapp/grails-app/conf/Config.groovy
Expand Up @@ -83,6 +83,8 @@ log4j={

warn 'org.mortbay.log'
warn 'grails.app.filters.AuthorizationFilters'

info 'com.dtolabs.rundeck.core.authorization.providers.SAREAuthorization'
}


0 comments on commit cf0ad7d

Please sign in to comment.