/*
 * 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.rest.auth;

import com.google.common.io.BaseEncoding;
import com.google.inject.Inject;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleResourceNotFoundException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.UserContext;
import org.apache.guacamole.GuacamoleSession;
import org.apache.guacamole.rest.APIRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A service for managing auth tokens via the Guacamole REST API.
 */
@Path("/tokens")
@Produces(MediaType.APPLICATION_JSON)
public class TokenRESTService {

    /**
     * Logger for this class.
     */
    private static final Logger logger = LoggerFactory.getLogger(TokenRESTService.class);

    /**
     * Service for authenticating users and managing their Guacamole sessions.
     */
    @Inject
    private AuthenticationService authenticationService;

    /**
     * Returns the credentials associated with the given request, using the
     * provided username and password.
     *
     * @param request
     *     The request to use to derive the credentials.
     *
     * @param username
     *     The username to associate with the credentials, or null if the
     *     username should be derived from the request.
     *
     * @param password
     *     The password to associate with the credentials, or null if the
     *     password should be derived from the request.
     *
     * @return
     *     A new Credentials object whose contents have been derived from the
     *     given request, along with the provided username and password.
     */
    private Credentials getCredentials(HttpServletRequest request,
            String username, String password) {

        // If no username/password given, try Authorization header
        if (username == null && password == null) {

            String authorization = request.getHeader("Authorization");
            if (authorization != null && authorization.startsWith("Basic ")) {

                try {

                    // Decode base64 authorization
                    String basicBase64 = authorization.substring(6);
                    String basicCredentials = new String(
                            BaseEncoding.base64().decode(basicBase64), "UTF-8");

                    // Pull username/password from auth data
                    int colon = basicCredentials.indexOf(':');
                    if (colon != -1) {
                        username = basicCredentials.substring(0, colon);
                        password = basicCredentials.substring(colon + 1);
                    }
                    else
                        logger.debug("Invalid HTTP Basic \"Authorization\" header received.");

                }

                // UTF-8 support is required by the Java specification
                catch (UnsupportedEncodingException e) {
                    throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e);
                }

            }

        } // end Authorization header fallback

        // Build credentials
        return new Credentials(username, password, request);

    }

    /**
     * Authenticates a user, generates an auth token, associates that auth token
     * with the user's UserContext for use by further requests. If an existing
     * token is provided, the authentication procedure will attempt to update
     * or reuse the provided token.
     *
     * @param username
     *     The username of the user who is to be authenticated.
     *
     * @param password
     *     The password of the user who is to be authenticated.
     *
     * @param token
     *     An optional existing auth token for the user who is to be
     *     authenticated.
     *
     * @param consumedRequest
     *     The HttpServletRequest associated with the login attempt. The
     *     parameters of this request may not be accessible, as the request may
     *     have been fully consumed by JAX-RS.
     *
     * @param parameters
     *     A MultivaluedMap containing all parameters from the given HTTP
     *     request. All request parameters must be made available through this
     *     map, even if those parameters are no longer accessible within the
     *     now-fully-consumed HTTP request.
     *
     * @return
     *     An authentication response object containing the possible-new auth
     *     token, as well as other related data.
     *
     * @throws GuacamoleException
     *     If an error prevents successful authentication.
     */
    @POST
    public APIAuthenticationResult createToken(@FormParam("username") String username,
            @FormParam("password") String password,
            @FormParam("token") String token,
            @Context HttpServletRequest consumedRequest,
            MultivaluedMap<String, String> parameters)
            throws GuacamoleException {

        // Reconstitute the HTTP request with the map of parameters
        HttpServletRequest request = new APIRequest(consumedRequest, parameters);

        // Build credentials from request
        Credentials credentials = getCredentials(request, username, password);

        // Create/update session producing possibly-new token
        token = authenticationService.authenticate(credentials, token);

        // Pull corresponding session
        GuacamoleSession session = authenticationService.getGuacamoleSession(token);
        if (session == null)
            throw new GuacamoleResourceNotFoundException("No such token.");

        // Build list of all available auth providers
        List<DecoratedUserContext> userContexts = session.getUserContexts();
        List<String> authProviderIdentifiers = new ArrayList<String>(userContexts.size());
        for (UserContext userContext : userContexts)
            authProviderIdentifiers.add(userContext.getAuthenticationProvider().getIdentifier());

        // Return possibly-new auth token
        AuthenticatedUser authenticatedUser = session.getAuthenticatedUser();
        return new APIAuthenticationResult(
            token,
            authenticatedUser.getIdentifier(),
            authenticatedUser.getAuthenticationProvider().getIdentifier(),
            authProviderIdentifiers
        );

    }

    /**
     * Invalidates a specific auth token, effectively logging out the associated
     * user.
     * 
     * @param authToken
     *     The token being invalidated.
     *
     * @throws GuacamoleException
     *     If the specified token does not exist.
     */
    @DELETE
    @Path("/{token}")
    public void invalidateToken(@PathParam("token") String authToken)
            throws GuacamoleException {

        // Invalidate session, if it exists
        if (!authenticationService.destroyGuacamoleSession(authToken))
            throw new GuacamoleResourceNotFoundException("No such token.");

    }

}
