mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-05 23:22:51 +00:00
Implement AccountDetails object that provides account information
This commit is contained in:
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.rogiel.httpchannel.captcha.Captcha;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.AccountDetails.PremiumAccountDetails;
|
||||
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
@@ -41,9 +42,9 @@ public abstract class AbstractService implements Service {
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The currently active service mode
|
||||
* The currently active account
|
||||
*/
|
||||
protected ServiceMode serviceMode = ServiceMode.UNAUTHENTICATED;
|
||||
protected AccountDetails account;
|
||||
|
||||
/**
|
||||
* This service {@link CaptchaService} that is used to resolve CAPTCHAS
|
||||
@@ -52,7 +53,16 @@ public abstract class AbstractService implements Service {
|
||||
|
||||
@Override
|
||||
public ServiceMode getServiceMode() {
|
||||
return serviceMode;
|
||||
if (account == null) {
|
||||
return ServiceMode.UNAUTHENTICATED;
|
||||
} else {
|
||||
if (account.is(PremiumAccountDetails.class)) {
|
||||
return (account.as(PremiumAccountDetails.class).isPremium() ? ServiceMode.PREMIUM
|
||||
: ServiceMode.NON_PREMIUM);
|
||||
} else {
|
||||
return ServiceMode.NON_PREMIUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,10 +4,149 @@
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
/**
|
||||
* An {@link AccountDetails} instance can provide several information about an
|
||||
* authenticated account. This instance itself provides little information,
|
||||
* restricted to whether the account {@link #isActive() is active} and its
|
||||
* {@link #getUsername() username}. More details are provided by additional
|
||||
* interfaces:
|
||||
* <ul>
|
||||
* <li>{@link PremiumAccountDetails} - for services that provide premium
|
||||
* accounts</li>
|
||||
* <li>{@link DiskQuotaAccountDetails} - for services that have limited disk
|
||||
* quota</li>
|
||||
* <li>{@link BandwidthQuotaAccountDetails} - for services that have limited
|
||||
* bandwidth quota</li>
|
||||
* </ul>
|
||||
* You should not try to cast instances by yourself, instead they should be
|
||||
* safely casted as such:
|
||||
*
|
||||
* <pre>
|
||||
* final {@link AccountDetails} details = ...;
|
||||
* if(details.{@link #is(Class) is}({@link PremiumAccountDetails}.class)) {
|
||||
* details.{@link #as(Class) as}({@link PremiumAccountDetails}.class).{@link PremiumAccountDetails#isPremium() isPremium()};
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* A single {@link AccountDetails} can implement none, one extended or even more
|
||||
* than one extended details interfaces, however all instances are required to
|
||||
* implement at least the basic methods defined in this interface.
|
||||
* <p>
|
||||
* Services could implement their own methods for details, but this should be
|
||||
* avoided because it would make user code dependent on implementation meta data
|
||||
* which is not stable and could break compatibility with other implementation
|
||||
* versions. If possible, it is recommended to add a new interface into the API
|
||||
* module.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface AccountDetails {
|
||||
/**
|
||||
* @return the account username
|
||||
*/
|
||||
String getUsername();
|
||||
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the account is currently active
|
||||
*/
|
||||
boolean isActive();
|
||||
|
||||
/**
|
||||
* @return the service that provided this account
|
||||
*/
|
||||
AuthenticationService<?> getService();
|
||||
|
||||
/**
|
||||
* Checks whether the account object can be casted to <code>type</code>
|
||||
*
|
||||
* @param type
|
||||
* the casting type
|
||||
* @return <code>true</code> if this object can be casted to
|
||||
* <code>type</code>
|
||||
*/
|
||||
boolean is(Class<? extends AccountDetails> type);
|
||||
|
||||
/**
|
||||
* Casts this object to <code>type</code>. If cannot be casted,
|
||||
* <code>null</code> is returned.
|
||||
*
|
||||
* @param type
|
||||
* the casting type
|
||||
* @return the casted account
|
||||
*/
|
||||
<T extends AccountDetails> T as(Class<T> type);
|
||||
|
||||
/**
|
||||
* Service accounts that has premium accounts must implement this interface
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface PremiumAccountDetails extends AccountDetails {
|
||||
/**
|
||||
* @return <code>true</code> if the account is premium
|
||||
*/
|
||||
boolean isPremium();
|
||||
}
|
||||
|
||||
/**
|
||||
* Service accounts that has accounts with limited disk space should
|
||||
* implement this interface
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface DiskQuotaAccountDetails extends AccountDetails {
|
||||
/**
|
||||
* @return the currently free disk space. <code>-1</code> means no limit
|
||||
*/
|
||||
long getFreeDiskSpace();
|
||||
|
||||
/**
|
||||
* @return the currently used disk space. Cannot be negative.
|
||||
*/
|
||||
long getUsedDiskSpace();
|
||||
|
||||
/**
|
||||
* @return the maximum amount of disk space. <code>-1</code> means no
|
||||
* limit
|
||||
*/
|
||||
long getMaximumDiskSpace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Service accounts that has accounts with limited bandwidth should
|
||||
* implement this interface
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface BandwidthQuotaAccountDetails extends AccountDetails {
|
||||
/**
|
||||
* @return the currently free bandwidth. <code>-1</code> means no limit
|
||||
*/
|
||||
long getFreeBandwidth();
|
||||
|
||||
/**
|
||||
* @return the currently used bandwidth. Cannot be negative.
|
||||
*/
|
||||
long getUsedBandwidth();
|
||||
|
||||
/**
|
||||
* @return the maximum amount of bandwidth available. <code>-1</code>
|
||||
* means no limit
|
||||
*/
|
||||
long getMaximumBandwidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Service accounts that has accounts with limited bandwidth should
|
||||
* implement this interface
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface FilesizeLimitAccountDetails extends AccountDetails {
|
||||
/**
|
||||
* @return the maximum filesize for the account. <code>-1</code> means
|
||||
* no limit
|
||||
*/
|
||||
long getMaximumFilesize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,10 @@ public interface AuthenticationService<C extends AuthenticatorConfiguration>
|
||||
* @see AuthenticatorCapability
|
||||
*/
|
||||
CapabilityMatrix<AuthenticatorCapability> getAuthenticationCapability();
|
||||
|
||||
/**
|
||||
* @return the currently authenticated account. Can be <code>null</code> and
|
||||
* this indicates that the service is not authenticated.
|
||||
*/
|
||||
AccountDetails getAccountDetails();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,16 @@ public interface Authenticator<C extends AuthenticatorConfiguration> {
|
||||
* persistent for the entire service's operation.<br>
|
||||
* <b>Note</b>: If you want to logout the user, see
|
||||
* {@link Authenticator#logout()}
|
||||
* <p>
|
||||
* Return <code>null</code> is only allowed if
|
||||
* {@link AuthenticatorCapability#ACCOUNT_DETAILS} is not supported by the
|
||||
* service.
|
||||
*
|
||||
* @return the authenticated account {@link AccountDetails}. If
|
||||
* {@link AuthenticationService#getAuthenticationCapability()}
|
||||
* contains {@link AuthenticatorCapability#ACCOUNT_DETAILS}
|
||||
* <code>null</code> cannot be returned. Otherwise,
|
||||
* <code>null</code> should always be returned.
|
||||
*
|
||||
* @throws IOException
|
||||
* if any IO error occur
|
||||
@@ -51,7 +61,8 @@ public interface Authenticator<C extends AuthenticatorConfiguration> {
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
void login() throws IOException, AuthenticationInvalidCredentialException,
|
||||
AccountDetails login() throws IOException,
|
||||
AuthenticationInvalidCredentialException,
|
||||
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ package com.rogiel.httpchannel.service;
|
||||
*/
|
||||
public enum AuthenticatorCapability {
|
||||
/**
|
||||
* Mark an {@link Authenticator} capable of fetching account information.
|
||||
* Mark an {@link Authenticator} capable of providing account details.
|
||||
*/
|
||||
FETCH_ACCOUNT_INFORMATION;
|
||||
ACCOUNT_DETAILS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user