package be.neutrinet.ispng.vpn; import be.neutrinet.ispng.security.OwnedEntity; import be.neutrinet.ispng.vpn.ip.SubnetLease; import com.fasterxml.jackson.annotation.JsonManagedReference; import com.j256.ormlite.dao.ForeignCollection; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.ForeignCollectionField; import com.j256.ormlite.table.DatabaseTable; import org.apache.log4j.Logger; import java.io.Serializable; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Optional; import java.util.UUID; /** * Created by wannes on 11/10/14. */ @DatabaseTable(tableName = "ovpn_clients") public class Client implements OwnedEntity, Serializable { @DatabaseField(generatedId = true) public int id; @DatabaseField(canBeNull = false) public String commonName; @DatabaseField(canBeNull = false) public UUID userId; @ForeignCollectionField(foreignFieldName = "client") @JsonManagedReference public ForeignCollection<IPAddress> leases; @ForeignCollectionField(foreignFieldName = "client") @JsonManagedReference public ForeignCollection<SubnetLease> subnetLeases; @DatabaseField(defaultValue = "true") public boolean enabled; private User user; public static Optional<Client> match(be.neutrinet.ispng.openvpn.Client vpnClient) { try { List<User> users = Users.query("email", vpnClient.username); assert users.size() == 1; User user = users.get(0); HashMap<String, Object> query = new HashMap<>(); query.put("userId", user.id); query.put("commonName", vpnClient.commonName); List<Client> clients = Clients.dao.queryForFieldValues(query); if (clients.size() > 1) { Logger.getLogger(Client.class).error("Multiple client definitions, user: " + vpnClient.username + ", commonName: " + vpnClient.commonName); return Optional.empty(); } if (clients.isEmpty()) return Optional.empty(); else return Optional.of(clients.get(0)); } catch (Exception ex) { Logger.getLogger(Client.class).warn("Failed to match VPN client for " + vpnClient.username, ex); } return Optional.empty(); } public static Client create(be.neutrinet.ispng.openvpn.Client client) { Client c = new Client(); c.commonName = client.commonName; try { c.subnetLeases = Clients.dao.getEmptyForeignCollection("subnetLeases"); List<User> users = Users.query("email", client.username); assert users.size() == 1; User user = users.get(0); c.userId = user.id; c.enabled = true; Clients.dao.createIfNotExists(c); } catch (Exception ex) { Logger.getLogger(Client.class).error("Failed to create VPN client for user " + client.username, ex); } return c; } public IPAddress getOrCreateInterconnectIP(int ipVersion) { IPAddress interconnect = null; List<IPAddress> interconnects = IPAddresses.forClient(this, ipVersion, IPAddress.Purpose.INTERCONNECT); if (interconnects.size() < 1) { interconnect = IPAddresses.findUnused(6, IPAddress.Purpose.INTERCONNECT).orElseThrow(() -> new IllegalStateException("No interconnect IPs available")); try { interconnect.client = this; IPAddresses.dao.update(interconnect); } catch (SQLException ex) { Logger.getLogger(getClass()).error("Failed to update interconnect IP information", ex); } } else { interconnect = interconnects.get(0); } return interconnect; } public User user() { if (user == null) user = Users.queryForId(userId); return user; } @Override public boolean isOwnedBy(UUID user) { return this.userId.equals(user); } }