All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.linguafranca.pwdb.kdbx.jackson.JacksonEntry Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2023 Giuseppe Valente
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.linguafranca.pwdb.kdbx.jackson;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.jetbrains.annotations.NotNull;

import org.linguafranca.pwdb.base.AbstractEntry;
import org.linguafranca.pwdb.kdbx.Helpers;
import org.linguafranca.pwdb.kdbx.jackson.converter.Base64ToUUIDConverter;
import org.linguafranca.pwdb.kdbx.jackson.converter.UUIDToBase64Converter;

import org.linguafranca.pwdb.kdbx.jackson.model.KeePassFile;
import org.linguafranca.pwdb.kdbx.jackson.model.Times;
import org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses.AutoType;
import org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses.BinaryProperty;
import org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses.StringProperty;

import static org.linguafranca.pwdb.kdbx.jackson.model.EntryClasses.*;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;



@JsonPropertyOrder({
    "uuid",
    "iconID",
    "customIconUUID",
    "foregroundColor",
    "backgroundColor",
    "overrideURL",
    "tags",
    "times",
    "string",
    "binary",
    "autoType",
    "history",
})


@JsonIgnoreProperties({"path", "username", "title", "notes", "url", "password"})
public class JacksonEntry extends AbstractEntry {


    @JacksonXmlProperty(localName = "UUID")
    @JsonDeserialize(converter = Base64ToUUIDConverter.class)
    @JsonSerialize(converter = UUIDToBase64Converter.class)
    protected UUID uuid;

    @JacksonXmlProperty(localName = "IconID")
    protected int iconID;
    
    @JacksonXmlProperty(localName = "CustomIconUUID")
    @JsonDeserialize(converter = Base64ToUUIDConverter.class)
    @JsonSerialize(converter = UUIDToBase64Converter.class)
    protected UUID customIconUUID;
   
    @JacksonXmlProperty(localName = "ForegroundColor")
    protected String foregroundColor;
    
    @JacksonXmlProperty(localName = "BackgroundColor")
    protected String backgroundColor;
   
    @JacksonXmlProperty(localName = "OverrideURL")
    protected String overrideURL;
    
    @JacksonXmlProperty(localName = "Tags")
    protected String tags;
   
    @JacksonXmlProperty(localName = "Times")
    protected Times times;

    @JacksonXmlProperty(localName = "String") /* Workaround jackson */
    @JacksonXmlElementWrapper(useWrapping = false)
    protected List string;

    @JacksonXmlProperty(localName = "Binary") /* Workaround jackson */
    @JacksonXmlElementWrapper(useWrapping = false)
    protected List binary;

    @JacksonXmlProperty(localName = "AutoType")
    protected AutoType autoType;

    @JacksonXmlProperty(localName = "History") /* Workaround jackson */
    protected JacksonHistory history;

    @JsonIgnore
    JacksonDatabase database;

    @JsonIgnore
    JacksonGroup parent;

    protected JacksonEntry() {
        string = new ArrayList<>();
        binary = new ArrayList<>();
        times = new Times();
        uuid = UUID.randomUUID();
        iconID = 0;
    }

    public static JacksonEntry createEntry(JacksonDatabase database) {
        JacksonEntry result = new JacksonEntry();
        result.database = database;
        result.parent = null;
        // avoiding setProperty as it does a touch();
        for (String p : STANDARD_PROPERTY_NAMES) {
            result.string.add(new StringProperty(p, new StringProperty.Value("")));
        }
        return result;
    }

    @Override
    @JsonIgnore
    public String getProperty(String s) {
        return getStringContent(getStringProperty(s, string));
    }

    @Override
    @JsonIgnore
    public void setProperty(String s, String s1) {
        StringProperty sp;
        if ((sp = getStringProperty(s, string)) != null) {
            this.string.remove(sp);
        }
        this.string.add(new StringProperty(s, new StringProperty.Value(s1)));
        touch();
    }

    @Override
    @JsonIgnore
    public boolean removeProperty(String name) throws IllegalArgumentException {
        if (STANDARD_PROPERTY_NAMES.contains(name))
            throw new IllegalArgumentException("may not remove property: " + name);

        StringProperty sp = getStringProperty(name, string);
        if (sp == null) {
            return false;
        } else {
            this.string.remove(sp);
            touch();
            return true;
        }
    }

    @Override
    @JsonIgnore
    public List getPropertyNames() {
        List result = new ArrayList<>();
        for (StringProperty property : this.string) {
            result.add(property.getKey());
        }
        return result;
    }

    @Override
    public byte[] getBinaryProperty(String s) {
        BinaryProperty bp = getBinaryProp(s, binary);
        if (bp == null) {
            return null;
        }

        KeePassFile.Binary binary = null;
        for (KeePassFile.Binary b : database.getBinaries()) {
            if (b.getId().equals(Integer.valueOf(getBinaryContent(bp)))) {
                binary = b;
            }
        }
        if (binary == null) {
            return null;
        }
        return Helpers.decodeBase64Content(binary.getValue().getBytes(), binary.getCompressed());
    }

    @Override
    public void setBinaryProperty(String s, byte[] bytes) {
        // remove old binary property with same name
        BinaryProperty bp = getBinaryProp(s, binary);
        if (bp != null) {
            binary.remove(bp);
        }

        // what is the next free index in the binary store?
        Integer max = -1;
        for (KeePassFile.Binary binary : database.getBinaries()) {
            if (binary.getId() > max) {
                max = binary.getId();
            }
        }
        max++;

        database.addBinary(bytes, max);

        // make a reference to it from the entry
        BinaryProperty binaryProperty = new BinaryProperty();
        binaryProperty.setKey(s);
        BinaryProperty.Value fieldValue = new BinaryProperty.Value();
        fieldValue.setRef(String.valueOf(max));
        binaryProperty.setValue(fieldValue);
        binary.add(binaryProperty);
        touch();
    }

    @Override
    @JsonIgnore
    public boolean removeBinaryProperty(String name) throws UnsupportedOperationException {
        BinaryProperty bp = getBinaryProp(name, binary);
        if (bp != null) {
            binary.remove(bp);
            touch();
            return true;
        }
        return false;
    }

    @Override
    @JsonIgnore
    public List getBinaryPropertyNames() {
        List result = new ArrayList<>();
        for (BinaryProperty property : this.binary) {
            result.add(property.getKey());
        }
        return result;
    }

    @Override
    public JacksonGroup getParent() {
        return parent;
    }

    @Override
    public @NotNull UUID getUuid() {
        return uuid;
    }

    @Override
    public JacksonIcon getIcon() {
        return new JacksonIcon(iconID);
    }

    @Override
    public void setIcon(JacksonIcon icon) {
        iconID = icon.getIndex();
    }

    @Override
    @JsonIgnore
    public Date getLastAccessTime() {
        return times.getLastAccessTime();
    }

    @Override
    @JsonIgnore
    public Date getCreationTime() {
        return times.getCreationTime();
    }

    @Override
    @JsonIgnore
    public boolean getExpires() {
        return times.getExpires();
    }

    @Override
    @JsonIgnore
    public void setExpires(boolean expires) {
        times.setExpires(expires);
    }

    @Override
    @JsonIgnore
    public Date getExpiryTime() {
        return times.getExpiryTime();
    }

    @Override
    @JsonIgnore
    public void setExpiryTime(Date expiryTime) throws IllegalArgumentException {
        if (expiryTime == null)
            throw new IllegalArgumentException("expiryTime may not be null");
        times.setExpiryTime(expiryTime);
    }

    @Override
    @JsonIgnore
    public Date getLastModificationTime() {
        return times.getLastModificationTime();
    }

    @Override
    @JsonIgnore
    protected void touch() {
        this.times.setLastModificationTime(new Date());
        this.database.setDirty(true);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy