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

com.github.zxbu.webdavteambition.manager.AliyunDriveSessionManager Maven / Gradle / Ivy

There is a newer version: 2.0.5
Show newest version
package com.github.zxbu.webdavteambition.manager;

import com.github.zxbu.webdavteambition.config.AliyunDriveProperties;
import com.github.zxbu.webdavteambition.inf.IBackgroundTask;
import net.xdow.aliyundrive.webapi.impl.AliyunDriveWebApiImplV1;
import org.bouncycastle.util.encoders.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Hash;
import org.web3j.crypto.Sign;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class AliyunDriveSessionManager implements IBackgroundTask {

    public static final int SIGN_EXPIRED_TIME_SEC = 60 * 5; //5min

    private static final Logger LOGGER = LoggerFactory.getLogger(AliyunDriveSessionManager.class);

    private final AliyunDriveWebApiImplV1 mAliyunDrive;
    private final AliyunDriveProperties mAliyunDriveProperties;
    private ScheduledExecutorService mTaskPool = Executors.newScheduledThreadPool(1);

    public AliyunDriveSessionManager(AliyunDriveWebApiImplV1 aliyunDrive, AliyunDriveProperties aliYunDriveProperties) {
        this.mAliyunDrive = aliyunDrive;
        this.mAliyunDriveProperties = aliYunDriveProperties;
        makeKeyPairIfNeeded();
    }

    public void makeKeyPairIfNeeded() {
        AliyunDriveProperties.Session session = this.mAliyunDriveProperties.getSession();
        if (!session.isEmpty()) {
            return;
        }
        makeKeyPair();
    }

    public void makeKeyPair() {
        AliyunDriveProperties.Session session = this.mAliyunDriveProperties.getSession();
        BigInteger privateKeyInt = new BigInteger(256, new SecureRandom());
        BigInteger publicKeyInt = Sign.publicKeyFromPrivate(privateKeyInt);
        session.setPrivateKey(privateKeyInt.toString(16));
        session.setPublicKey(publicKeyInt.toString(16));
        makeSignature(0);
        this.mAliyunDriveProperties.save();
    }

    private void makeSignature(int nonce) {
        AliyunDriveProperties aliYunDriveProperties = this.mAliyunDriveProperties;
        AliyunDriveProperties.Session session = aliYunDriveProperties.getSession();
        byte[] dataBytes = (aliYunDriveProperties.getAppId() + ":" + aliYunDriveProperties.getDeviceId() + ":"
                + aliYunDriveProperties.getUserId() + ":" + nonce).getBytes(StandardCharsets.UTF_8);
        byte[] dataHash = Hash.sha256(dataBytes);
        ECKeyPair keyPair = new ECKeyPair(new BigInteger(session.getPrivateKey(), 16),
                new BigInteger(session.getPublicKey(), 16));
        Sign.SignatureData signatureInfo = Sign.signMessage(dataHash, keyPair, false);
        session.setSignature(Hex.toHexString(signatureInfo.getR()) + Hex.toHexString(signatureInfo.getS()));
        session.setNonce(nonce);
        session.setExpireTimeSec(System.currentTimeMillis() / 1000 + SIGN_EXPIRED_TIME_SEC);
    }

    public void updateSession() {
        AliyunDriveProperties.Session session = this.mAliyunDriveProperties.getSession();
        String OS_NAME = System.getProperty("os.name");
        Map args = new HashMap<>();
        args.put("deviceName", "Webdav");
        if (OS_NAME.contains("Windows")) {
            args.put("modelName", OS_NAME);
        } else {
            args.put("modelName", OS_NAME + " " + System.getProperty("os.version"));
        }
        args.put("pubKey", "04" + session.getPublicKey());

        String createSessionResult = "";
        if (session.getNonce() >= 1073741823) {
            session.setNonce(0);
        }
        makeSignature(session.getNonce());
        if (session.getNonce() == 0) {
            createSessionResult = this.mAliyunDrive.post("https://api.aliyundrive.com/users/v1/users/device/create_session", args);
        } else {
            createSessionResult = this.mAliyunDrive.post("https://api.aliyundrive.com/users/v1/users/device/renew_session", args);
        }

        if (createSessionResult != null) {
            if (createSessionResult.contains("DeviceSessionSignatureInvalid")
                    || createSessionResult.contains("UserDeviceOffline")) {
                makeKeyPair();
                createSessionResult = this.mAliyunDrive.post("https://api.aliyundrive.com/users/v1/users/device/create_session", args);
            }
        }
        if (createSessionResult.contains("\"result\":false")) {
            LOGGER.error("登录设备过多, 请进入\"登录设备管理\", 退出一些设备, 如设备被意外退出登录, 请手动删除配置文件后重启程序。");
            session.setNonce(0);
        }
        if (createSessionResult.contains("\"result\":true")) {
            session.setNonce(session.getNonce() + 1);
        }
        this.mAliyunDriveProperties.save();
    }

    public void start() {
        updateSession();
        mTaskPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                AliyunDriveProperties.Session session = AliyunDriveSessionManager.this.mAliyunDriveProperties.getSession();
                if (!session.isExpired()) {
                    return;
                }
                AliyunDriveSessionManager.this.updateSession();
            }
        }, 10, 10, TimeUnit.SECONDS);
    }

    public void stop() {
        mTaskPool.shutdownNow();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy