Package com.sk89q.skmcl.session

Source Code of com.sk89q.skmcl.session.YggdrasilSession$Agent

/*
* SK's Minecraft Launcher
* Copyright (C) 2010, 2011 Albert Pham <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.skmcl.session;

import com.sk89q.skmcl.util.HttpRequest;
import lombok.*;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import java.io.IOException;
import java.net.URL;
import java.util.List;

import static com.sk89q.skmcl.util.SharedLocale._;

/**
* Implements the Yggdrasil authentication scheme.
*/
@ToString(exclude = "password")
public class YggdrasilSession implements Session {

    private static final URL AUTH_URL =
            HttpRequest.url("https://authserver.mojang.com/authenticate");
    private static final URL REFRESH_URL =
            HttpRequest.url("https://authserver.mojang.com/refresh");

    private final String id;
    @Getter @Setter
    private List<Identity> identities;
    @Getter @Setter
    private String password;
    @Getter @Setter
    private String clientToken;
    @Getter @Setter
    private String accessToken;

    /**
     * Construct a login session using the given login ID.
     *
     * @param id email address or username
     */
    public YggdrasilSession(@NonNull String id) {
        this.id = id;
    }

    @Override
    public boolean isValid() {
        return accessToken != null;
    }

    public YggdrasilSession verify() throws AuthenticationException, InterruptedException, IOException {
        if (password != null && !password.isEmpty()) {
            authenticate();
        } else if (accessToken != null && clientToken != null) {
            refresh();
        } else {
            throw new AuthenticationException("Missing password/details", _("errors.incompleteCredentials"));
        }

        return this;
    }

    private void authenticate() throws IOException, InterruptedException, AuthenticationException {
        Object payload = new AuthenticatePayload(id, password);

        HttpRequest request = HttpRequest
                .post(AUTH_URL)
                .bodyJson(payload)
                .execute();

        if (request.getResponseCode() != 200) {
            ErrorResponse error = request.returnContent().asJson(ErrorResponse.class);
            throw new AuthenticationException(error.getErrorMessage(), error.getErrorMessage());
        } else {
            AuthenticateResponse response =
                    request.returnContent().asJson(AuthenticateResponse.class);
            accessToken = response.getAccessToken();
            clientToken = response.getClientToken();
            identities = response.getAvailableProfiles();
            for (Identity identity : identities) {
                identity.setAccessToken(accessToken);
                identity.setClientToken(clientToken);
            }
        }
    }

    private void refresh() throws IOException, InterruptedException, AuthenticationException {
        Object payload = new RefreshPayload(accessToken, clientToken);

        HttpRequest request = HttpRequest
                .post(REFRESH_URL)
                .bodyJson(payload)
                .execute();

        if (request.getResponseCode() != 200) {
            ErrorResponse error = request.returnContent().asJson(ErrorResponse.class);
            throw new AuthenticationException(error.getErrorMessage(), error.getErrorMessage());
        } else {
            AuthenticateResponse response =
                    request.returnContent().asJson(AuthenticateResponse.class);
            accessToken = response.getAccessToken();
            clientToken = response.getClientToken();
            identities = response.getAvailableProfiles();
            for (Identity identity : identities) {
                identity.setAccessToken(accessToken);
                identity.setClientToken(clientToken);
            }
        }
    }

    @Data
    private static class Agent {
        private final String name = "Minecraft";
        private final int version = 1;
    }

    @Data
    private static class AuthenticatePayload {
        private final Agent agent = new Agent();
        private final String username;
        private final String password;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class AuthenticateResponse {
        private String accessToken;
        private String clientToken;
        private List<Identity> availableProfiles;
        private Identity selectedProfile;
    }

    @Data
    private static class RefreshPayload {
        private final String accessToken;
        private final String clientToken;
        private Identity selectedProfile;
    }

    @Data
    private static class ErrorResponse {
        private String error;
        private String errorMessage;
        private String cause;
    }

}
TOP

Related Classes of com.sk89q.skmcl.session.YggdrasilSession$Agent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.