/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.guacamole.auth.totp.form;

import com.google.common.io.BaseEncoding;
import com.google.inject.Inject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.UriBuilder;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.totp.user.UserTOTPKey;
import org.apache.guacamole.auth.totp.conf.ConfigurationService;
import org.apache.guacamole.form.Field;
import org.apache.guacamole.totp.TOTPGenerator;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * Field which prompts the user for an authentication code generated via TOTP.
 */
public class AuthenticationCodeField extends Field {

    /**
     * The name of the HTTP parameter which will contain the TOTP code provided
     * by the user to verify their identity.
     */
    public static final String PARAMETER_NAME = "guac-totp";

    /**
     * The unique name associated with this field type.
     */
    private static final String FIELD_TYPE_NAME = "GUAC_TOTP_CODE";

    /**
     * The width of QR codes to generate, in pixels.
     */
    private static final int QR_CODE_WIDTH = 256;

    /**
     * The height of QR codes to generate, in pixels.
     */
    private static final int QR_CODE_HEIGHT = 256;

    /**
     * BaseEncoding which encodes/decodes base32.
     */
    private static final BaseEncoding BASE32 = BaseEncoding.base32();

    /**
     * Service for retrieving configuration information.
     */
    @Inject
    private ConfigurationService confService;

    /**
     * The TOTP key to expose to the user for the sake of enrollment, if any.
     * If no such key should be exposed to the user, this will be null.
     */
    private UserTOTPKey key;

    /**
     * Creates a new field which prompts the user for an authentication code
     * generated via TOTP. The user's TOTP key is not exposed for enrollment.
     */
    public AuthenticationCodeField() {
        super(PARAMETER_NAME, FIELD_TYPE_NAME);
    }

    /**
     * Exposes the given key to facilitate enrollment.
     *
     * @param key
     *     The TOTP key to expose to the user for the sake of enrollment.
     */
    public void exposeKey(UserTOTPKey key) {
        this.key = key;
    }

    /**
     * Returns the username of the user associated with the key being used to
     * generate TOTP codes. If the user's key is not being exposed to facilitate
     * enrollment, this value will not be exposed either.
     *
     * @return
     *     The username of the user associated with the key being used to
     *     generate TOTP codes, or null if the user's key is not being exposed
     *     to facilitate enrollment.
     */
    public String getUsername() {

        // Do not reveal TOTP mode unless enrollment is in progress
        if (key == null)
            return null;

        return key.getUsername();

    }

    /**
     * Returns the base32-encoded secret key that is being used to generate TOTP
     * codes for the authenticating user. If the user's key is not being exposed
     * to facilitate enrollment, this value will not be exposed either.
     *
     * @return
     *     The base32-encoded secret key that is being used to generate TOTP
     *     codes for the authenticating user, or null if the user's key is not
     *     being exposed to facilitate enrollment.
     */
    public String getSecret() {

        // Do not reveal TOTP mode unless enrollment is in progress
        if (key == null)
            return null;

        return BASE32.encode(key.getSecret());

    }

    /**
     * Returns the number of digits used for each TOTP code. If the user's key
     * is not being exposed to facilitate enrollment, this value will not be
     * exposed either.
     *
     * @return
     *     The number of digits used for each TOTP code, or null if the user's
     *     key is not being exposed to facilitate enrollment.
     *
     * @throws GuacamoleException
     *     If the number of digits cannot be read from guacamole.properties.
     */
    public Integer getDigits() throws GuacamoleException {

        // Do not reveal code size unless enrollment is in progress
        if (key == null)
            return null;

        return confService.getDigits();
        
    }

    /**
     * Returns the human-readable name of the entity issuing user accounts. If
     * the user's key is not being exposed to facilitate enrollment, this value
     * will not be exposed either.
     *
     * @return
     *     The human-readable name of the entity issuing user accounts, or null
     *     if the user's key is not being exposed to facilitate enrollment.
     *
     * @throws GuacamoleException
     *     If the issuer cannot be read from guacamole.properties.
     */
    public String getIssuer() throws GuacamoleException {

        // Do not reveal code issuer unless enrollment is in progress
        if (key == null)
            return null;

        return confService.getIssuer();

    }

    /**
     * Returns the mode that TOTP code generation is operating in. This value
     * will be one of "SHA1", "SHA256", or "SHA512". If the user's key is not
     * being exposed to facilitate enrollment, this value will not be exposed
     * either.
     *
     * @return
     *     The mode that TOTP code generation is operating in, such as "SHA1",
     *     "SHA256", or "SHA512", or null if the user's key is not being
     *     exposed to facilitate enrollment.
     *
     * @throws GuacamoleException
     *     If the TOTP mode cannot be read from guacamole.properties.
     */
    public TOTPGenerator.Mode getMode() throws GuacamoleException {

        // Do not reveal TOTP mode unless enrollment is in progress
        if (key == null)
            return null;

        return confService.getMode();

    }

    /**
     * Returns the number of seconds that each TOTP code remains valid. If the
     * user's key is not being exposed to facilitate enrollment, this value will
     * not be exposed either.
     *
     * @return
     *     The number of seconds that each TOTP code remains valid, or null if
     *     the user's key is not being exposed to facilitate enrollment.
     *
     * @throws GuacamoleException
     *     If the period cannot be read from guacamole.properties.
     */
    public Integer getPeriod() throws GuacamoleException {

        // Do not reveal code period unless enrollment is in progress
        if (key == null)
            return null;

        return confService.getPeriod();

    }

    /**
     * Returns the "otpauth" URI for the secret key used to generate TOTP codes
     * for the current user. If the secret key is not being exposed to
     * facilitate enrollment, null is returned.
     *
     * @return
     *     The "otpauth" URI for the secret key used to generate TOTP codes
     *     for the current user, or null is the secret ket is not being exposed
     *     to facilitate enrollment.
     *
     * @throws GuacamoleException
     *     If the configuration information required for generating the key URI
     *     cannot be read from guacamole.properties.
     */
    @JsonProperty("keyUri")
    public URI getKeyURI() throws GuacamoleException {

        // Do not generate a key URI if no key is being exposed
        if (key == null)
            return null;

        // Format "otpauth" URL (see https://github.com/google/google-authenticator/wiki/Key-Uri-Format)
        String issuer = confService.getIssuer();
        return UriBuilder.fromUri("otpauth://totp/")
                .path(issuer + ":" + key.getUsername())
                .queryParam("secret", BASE32.encode(key.getSecret()))
                .queryParam("issuer", issuer)
                .queryParam("algorithm", confService.getMode())
                .queryParam("digits", confService.getDigits())
                .queryParam("period", confService.getPeriod())
                .build();

    }

    /**
     * Returns the URL of a QR code describing the user's TOTP key and
     * configuration. If the key is not being exposed for enrollment, null is
     * returned.
     *
     * @return 
     *     The URL of a QR code describing the user's TOTP key and
     *     configuration, or null if the key is not being exposed for
     *     enrollment.
     *
     * @throws GuacamoleException
     *     If the configuration information required for generating the QR code
     *     cannot be read from guacamole.properties.
     */
    @JsonProperty("qrCode")
    public String getQRCode() throws GuacamoleException {

        // Do not generate a QR code if no key is being exposed
        URI keyURI = getKeyURI();
        if (keyURI == null)
            return null;

        ByteArrayOutputStream stream = new ByteArrayOutputStream();

        try {

            // Create QR code writer
            QRCodeWriter writer = new QRCodeWriter();
            BitMatrix matrix = writer.encode(keyURI.toString(),
                    BarcodeFormat.QR_CODE, QR_CODE_WIDTH, QR_CODE_HEIGHT);

            // Produce PNG image of TOTP key text
            MatrixToImageWriter.writeToStream(matrix, "PNG", stream);

        }
        catch (WriterException e) {
            throw new IllegalArgumentException("QR code could not be "
                    + "generated for TOTP key.", e);
        }
        catch (IOException e) {
            throw new IllegalStateException("Image stream of QR code could "
                    + "not be written.", e);
        }

        // Return data URI for generated image
        return "data:image/png;base64,"
                + BaseEncoding.base64().encode(stream.toByteArray());

    }

}
