/*
 * Copyright 2014 Red Hat, Inc.
 *
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  and Apache License v2.0 which accompanies this distribution.
 *
 *  The Eclipse Public License is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  The Apache License v2.0 is available at
 *  http://www.opensource.org/licenses/apache2.0.php
 *
 *  You may elect to redistribute this code under either of these licenses.
 */

package io.vertx.ext.auth;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.shareddata.impl.ClusterSerializable;

import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;

Useful base class for implementing a User object.

This class handles the caching logic so you can concentrate on the actual authorisation logic.

Just implement the abstract methods in your concrete sub-class.

Author:Tim Fox
/** * Useful base class for implementing a User object. * <p> * This class handles the caching logic so you can concentrate on the actual authorisation logic. * <p> * Just implement the abstract methods in your concrete sub-class. * * @author <a href="http://tfox.org">Tim Fox</a> */
public abstract class AbstractUser implements User, ClusterSerializable { private final Set<String> cachedPermissions = new HashSet<>(); @Override public User isAuthorized(String authority, Handler<AsyncResult<Boolean>> resultHandler) { if (cachedPermissions.contains(authority)) { resultHandler.handle(Future.succeededFuture(true)); } else { doIsPermitted(authority, res -> { if (res.succeeded()) { if (res.result()) { cachedPermissions.add(authority); } } resultHandler.handle(res); }); } return this; } @Override public User clearCache() { cachedPermissions.clear(); return this; } @Override public void writeToBuffer(Buffer buff) { writeStringSet(buff, cachedPermissions); } @Override public int readFromBuffer(int pos, Buffer buffer) { pos = readStringSet(buffer, cachedPermissions, pos); return pos; } public boolean cachePermission(String authority) { return cachedPermissions.add(authority); } protected abstract void doIsPermitted(String permission, Handler<AsyncResult<Boolean>> resultHandler); private void writeStringSet(Buffer buff, Set<String> set) { buff.appendInt(set == null ? 0 : set.size()); if (set != null) { for (String entry : set) { byte[] bytes = entry.getBytes(StandardCharsets.UTF_8); buff.appendInt(bytes.length).appendBytes(bytes); } } } private int readStringSet(Buffer buffer, Set<String> set, int pos) { int num = buffer.getInt(pos); pos += 4; for (int i = 0; i < num; i++) { int len = buffer.getInt(pos); pos += 4; byte[] bytes = buffer.getBytes(pos, pos + len); pos += len; set.add(new String(bytes, StandardCharsets.UTF_8)); } return pos; } }