org.bimserver.webservices.authorization.Authorization Maven / Gradle / Ivy
package org.bimserver.webservices.authorization;
/******************************************************************************
* Copyright (C) 2009-2016 BIMserver.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see {@literal }.
*****************************************************************************/
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.TimeUnit;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bimserver.models.store.Project;
import org.bimserver.models.store.User;
import org.bimserver.models.store.UserType;
import org.bimserver.shared.exceptions.UserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class Authorization {
private static final Logger LOGGER = LoggerFactory.getLogger(Authorization.class);
private final GregorianCalendar expires = new GregorianCalendar();
private long uoid = -1;
public Authorization(int expires, TimeUnit expiresUnit) {
this.expires.add(Calendar.SECOND, (int) TimeUnit.SECONDS.convert(expires, expiresUnit));
}
public Authorization() {
}
public GregorianCalendar getExpires() {
return expires;
}
public void canDownload(long roid) throws UserException {
}
public void canCheckin(long poid) throws UserException {
}
public void canReadExtendedData(long roid) throws UserException {
}
public void canWriteExtendedData(long roid) throws UserException {
}
protected abstract int getBufferSize();
protected abstract byte getId();
public boolean hasRightsOnProjectOrSuperProjectsOrSubProjects(User user, Project project) {
if (user == null) {
return false;
}
if (user.getUserType() == UserType.ADMIN || user.getUserType() == UserType.SYSTEM) {
return true;
}
while (project != null) {
if (hasRightsOnProjectOrSubProjects(user, project)) {
return true;
}
project = project.getParent();
}
return false;
}
public boolean hasRightsOnProjectOrSuperProjects(User user, Project project) {
if (user.getUserType() == UserType.ADMIN || user.getUserType() == UserType.SYSTEM) {
return true;
}
if (hasRightsOnProject(user, project)) {
return true;
}
if (project.getParent() != null) {
if (hasRightsOnProjectOrSuperProjects(user, project.getParent())) {
return true;
}
}
return false;
}
public boolean hasRightsOnProjectOrSubProjects(User user, Project project) {
if (user.getUserType() == UserType.ADMIN || user.getUserType() == UserType.SYSTEM) {
return true;
}
if (hasRightsOnProject(user, project)) {
return true;
}
for (Project subProject : project.getSubProjects()) {
if (hasRightsOnProjectOrSubProjects(user, subProject)) {
return true;
}
}
return false;
}
public boolean hasRightsOnProject(User user, Project project) {
if (user.getUserType() == UserType.ADMIN || user.getUserType() == UserType.SYSTEM) {
return true;
}
for (User authorizedUser : project.getHasAuthorizedUsers()) {
if (authorizedUser == user) {
return true;
}
}
return false;
}
protected abstract void getBytes(ByteBuffer buffer);
public String asHexToken(Key key) {
try {
Cipher encodingCipher = Cipher.getInstance("AES");
encodingCipher.init(Cipher.ENCRYPT_MODE, key);
ByteBuffer buffer = ByteBuffer.allocate(16 + 1 + 8 + 8 + getBufferSize());
buffer.position(16);
buffer.put(getId());
buffer.putLong(getExpires().getTimeInMillis());
buffer.putLong(getUoid());
getBytes(buffer);
if (buffer.position() != buffer.capacity()) {
throw new RuntimeException("Buffer's position should be at the end " + buffer.position() + "/" + buffer.capacity());
}
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
buffer.position(16);
messageDigest.update(buffer);
buffer.position(0);
buffer.put(messageDigest.digest());
byte[] encodedBytes = encodingCipher.doFinal(buffer.array());
String encodedHexString = new String(Hex.encodeHex(encodedBytes));
return encodedHexString;
} catch (Exception e) {
LOGGER.error("", e);
}
return null;
}
public static Authorization fromToken(SecretKeySpec key, String token) throws AuthenticationException {
if (token == null) {
throw new IllegalArgumentException("Token required");
}
try {
int hashSizeBytes = 16;
Cipher decodingCipher = Cipher.getInstance("AES");
decodingCipher.init(Cipher.DECRYPT_MODE, key);
ByteBuffer buffer = ByteBuffer.wrap(decodingCipher.doFinal(Hex.decodeHex(token.toCharArray())));
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] foundHash = new byte[hashSizeBytes];
buffer.get(foundHash, 0, hashSizeBytes);
byte[] hashInput = new byte[buffer.capacity() - hashSizeBytes];
buffer.get(hashInput);
buffer.position(hashSizeBytes);
byte[] calculatedHash = messageDigest.digest(hashInput);
if (Arrays.equals(foundHash, calculatedHash)) {
byte type = buffer.get();
Authorization authorization = null;
long expires = buffer.getLong();
long uoid = buffer.getLong();
switch (type) {
case ExplicitRightsAuthorization.ID:
authorization = ExplicitRightsAuthorization.fromBuffer(buffer);
break;
case UserAuthorization.ID:
authorization = UserAuthorization.fromBuffer(buffer);
break;
case SystemAuthorization.ID:
authorization = SystemAuthorization.fromBuffer(buffer);
break;
case AnonymousAuthorization.ID:
authorization = AnonymousAuthorization.fromBuffer(buffer);
break;
case AdminAuthorization.ID:
authorization = AdminAuthorization.fromBuffer(buffer);
break;
default:
throw new AuthenticationException("Unknown authorization type: " + type);
}
authorization.setUoid(uoid);
authorization.setExpires(expires);
if (authorization.getExpires().getTimeInMillis() < new GregorianCalendar().getTimeInMillis()) {
throw new AuthenticationException("This token has expired");
}
return authorization;
} else {
throw new AuthenticationException("Given token is corrupt");
}
} catch (GeneralSecurityException e) {
throw new AuthenticationException("Invalid token", e);
} catch (DecoderException e) {
throw new AuthenticationException(e);
}
}
private void setExpires(long expires) {
this.expires.setTimeInMillis(expires);
}
public long getUoid() {
return uoid;
}
public void setUoid(long uoid) {
this.uoid = uoid;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy