/*
 * Copyright 2013 gitblit.com.
 *
 * 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 com.gitblit.auth;

import java.io.File;

import org.jvnet.libpam.PAM;
import org.jvnet.libpam.PAMException;
import org.jvnet.libpam.impl.CLibrary;

import com.gitblit.Constants;
import com.gitblit.Constants.AccountType;
import com.gitblit.Keys;
import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
import com.gitblit.models.UserModel;

/**
 * Implementation of PAM authentication for Linux/Unix/MacOSX.
 *
 * @author James Moger
 */
public class PAMAuthProvider extends UsernamePasswordAuthenticationProvider {

    public PAMAuthProvider() {
        super("pam");
    }

    @Override
    public void setup() {
        // Try to identify the passwd database
        String [] files = { "/etc/shadow", "/etc/master.passwd" };
		File passwdFile = null;
		for (String name : files) {
			File f = new File(name);
			if (f.exists()) {
				passwdFile = f;
				break;
			}
		}
		if (passwdFile == null) {
			logger.error("PAM Authentication could not find a passwd database!");
		} else if (!passwdFile.canRead()) {
			logger.error("PAM Authentication can not read passwd database {}! PAM authentications may fail!", passwdFile);
		}
    }

    @Override
    public boolean supportsCredentialChanges() {
        return false;
    }

    @Override
    public boolean supportsDisplayNameChanges() {
        return true;
    }

    @Override
    public boolean supportsEmailAddressChanges() {
        return true;
    }

    @Override
    public boolean supportsTeamMembershipChanges() {
        return true;
    }

	 @Override
	public AccountType getAccountType() {
		return AccountType.PAM;
	}

    @Override
    public UserModel authenticate(String username, char[] password) {
		if (CLibrary.libc.getpwnam(username) == null) {
			logger.warn("Can not get PAM passwd for " + username);
			return null;
		}

		PAM pam = null;
		try {
			String serviceName = settings.getString(Keys.realm.pam.serviceName, "system-auth");
			pam = new PAM(serviceName);
			pam.authenticate(username, new String(password));
		} catch (PAMException e) {
			logger.error(e.getMessage());
			return null;
		} finally {
			if (pam != null) {
				pam.dispose();
			}
		}

        UserModel user = userManager.getUserModel(username);
        if (user == null) {
        	// create user object for new authenticated user
        	user = new UserModel(username.toLowerCase());
        }

        // create a user cookie
        setCookie(user, password);

        // update user attributes from UnixUser
        user.accountType = getAccountType();
        user.password = Constants.EXTERNAL_ACCOUNT;

        // TODO consider mapping PAM groups to teams

        // push the changes to the backing user service
        updateUser(user);

        return user;
    }
}
