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

scouter.server.account.AccountManager.scala Maven / Gradle / Ivy

There is a newer version: 2.20.0
Show newest version
/*
*  Copyright 2015 the original author or authors. 
 *  @https://github.com/scouter-project/scouter
 *
 *  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 scouter.server.account;

import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.util.ArrayList
import java.util.Enumeration
import java.util.List
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import scouter.server.Configure
import scouter.server.Logger
import scouter.lang.Account
import scouter.lang.pack.MapPack
import scouter.lang.value.MapValue
import scouter.lang.value.Value
import scouter.util.CipherUtil
import scouter.util.FileUtil
import scouter.util.StringKeyLinkedMap
import scouter.util.ThreadUtil
import scouter.server.util.ThreadScala
import scouter.server.core.CoreRun

object AccountManager {
    val ACCOUNT_FILENAME = "account.xml";
    val GROUP_FILENAME = "account_group.xml";
    var accountMap = new StringKeyLinkedMap[Account]();
    var groupPolicyMap = new StringKeyLinkedMap[MapValue]();
    val confPath = Configure.CONF_DIR;  
    var conf = Configure.getInstance();
    FileUtil.mkdirs(confPath);
    val groupFile = new File(confPath + GROUP_FILENAME);
    val accountFile = new File(confPath + ACCOUNT_FILENAME);
    loadGroupFile();
    loadAccountFile();
    var lastModifiedAccountFile = 0L
    var lastModifiedGroupFile = 0L
    ThreadScala.startDaemon("scouter.server.account.AccountManager", { CoreRun.running }, 5000) {
        if (groupFile.lastModified() != lastModifiedGroupFile) {
            loadGroupFile();
        }
        if (accountFile.lastModified() != lastModifiedAccountFile) {
            loadAccountFile();
        }
    }
    private def loadGroupFile() {
        this.synchronized {
            try {
                Logger.println("Load Account Group File");
                if (groupFile.canRead() == false) {
                    var in: InputStream = null;
                    var fos: FileOutputStream = null;
                    var copyFailed = true;
                    var tryCnt = 0;
                    while (copyFailed) {
                        try {
                            tryCnt += 1;
                            in = AccountManager.getClass().getResourceAsStream("/scouter/server/account/" + GROUP_FILENAME);
                            fos = new FileOutputStream(groupFile);
                            fos.write(FileUtil.readAll(in));
                            copyFailed = false;
                        } catch {
                            case e: Exception =>
                                e.printStackTrace();
                                if (tryCnt > 3) {
                                    throw new RuntimeException("Cannot copy account_group.xml");
                                }
                                ThreadUtil.sleep(2000);
                        } finally {
                            FileUtil.close(fos);
                            FileUtil.close(in);
                        }
                    }
                }
                groupPolicyMap = GroupFileHandler.parse(groupFile);
                lastModifiedGroupFile = groupFile.lastModified();
            } catch {
                case e: Exception => e.printStackTrace();
                
            }
        }
    }
    private def loadAccountFile() {
        this.synchronized {
            try {
                Logger.println("Load Account File");
                if (accountFile.canRead() == false) {
                    var in: InputStream = null;
                    var fos: FileOutputStream = null;
                    var copyFailed = true;
                    var tryCnt = 0;
                    while (copyFailed) {
                        try {
                            tryCnt += 1;
                            in = AccountManager.getClass().getResourceAsStream("/scouter/server/account/" + ACCOUNT_FILENAME);
                            fos = new FileOutputStream(accountFile);
                            fos.write(FileUtil.readAll(in));
                            copyFailed = false;
                        } catch {
                            case e: Exception =>
                                e.printStackTrace();
                                if (tryCnt > 3) {
                                    throw new RuntimeException("Cannot copy account.xml");
                                }
                                ThreadUtil.sleep(2000);
                        } finally {
                            FileUtil.close(fos);
                            FileUtil.close(in);
                        }
                    }
                }
                accountMap = AccountFileHandler.parse(accountFile);
                lastModifiedAccountFile = accountFile.lastModified();
            } catch {
                case e: Exception => e.printStackTrace();
            }
        }
    }
    def authorizeAccount(id: String, pass: String): Account = {
        if(conf.getBoolean("account_use_ldap",false)){
          var ctx : DirContext = null;
          var props : Properties = new Properties();
          
          props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
          props.setProperty(Context.PROVIDER_URL, conf.getValue("account_ldap_provider_url"));
          props.setProperty(Context.SECURITY_AUTHENTICATION, conf.getValue("account_ldap_auth=","simple"));
          props.setProperty(Context.SECURITY_PRINCIPAL, id+conf.getValue("account_ldap_principal_domain"));
          props.setProperty(Context.SECURITY_CREDENTIALS, pass);
          
          try{            
            ctx = new InitialDirContext(props);
            var cons : SearchControls = new SearchControls();
            cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
            var searchFilter : String = "(cn="+id+")";
            
            if(conf.getBoolean("account_ldap_debug", false)){
                Logger.println("ldap id : "+id);
                Logger.println("ldap pass : "+pass);
                Logger.println("ldap properties : "+props.toString());
              }
            
            var result = ctx.search(conf.getValue("account_ldap_basedn"), searchFilter, cons);
            var nextEntry : SearchResult = null;
            if(result.hasMore()){
                  var attrs = result.next().getAttributes();
                  var nmEnum = attrs.getIDs();
                  while(nmEnum.hasMore()){
                    var _id = nmEnum.next();
                    
                    if( id.equals( attrs.get(_id).get().toString()) ){
                      var account : Account = new Account();
                      account.id = id
                      try{
                        account.email = attrs.get(conf.getValue("account_ldap_email_id","")).get().toString();
                        account.group = attrs.get(conf.getValue("account_ldap_group_id","")).get().toString();
                      }catch{
                        case ne : NullPointerException => ne.printStackTrace()
                      }
                      return account;
                    }
                  }
             }
            }catch{
              case e: Exception => Logger.println("Ldap Account Error : "+e.toString()); e.printStackTrace();
            }finally{              
              if(null != ctx) ctx.close();
            }
        }else{
          val account = accountMap.get(id);
          if (account == null) {
              return null;
          }
          if (account.password.equals(pass)) {
              return account;
          }
        }
        return null;
    }
    def getAccountList(): List[Account] = {
        val list = new ArrayList[Account]();
        val accEnu = accountMap.values();
        while (accEnu.hasMoreElements()) {
            list.add(accEnu.nextElement());
        }
        return list;
    }
    def getGroupList(): Array[String] = {
        return groupPolicyMap.keyArray();
    }
    def addAccount(account: Account): Boolean = {
        this.synchronized {
            if (accountMap.get(account.id) != null) {
                return false;
            }
            try {
                AccountFileHandler.addAccount(accountFile, account);
                accountMap.put(account.id, account);
                lastModifiedAccountFile = accountFile.lastModified();
                return true;
            } catch {
                case e: Exception => e.printStackTrace();
            }
            return false;
        }
    }
    def editAccount(account: Account): Boolean = {
        this.synchronized {
            if (accountMap.get(account.id) == null) {
                return false;
            }
            try {
                AccountFileHandler.editAccount(accountFile, account);
                accountMap.put(account.id, account);
                lastModifiedAccountFile = accountFile.lastModified();
                return true;
            } catch {
                case e: Exception => e.printStackTrace();
            }
            return false;
        }
    }
    def addAccountGroup(pack: MapPack): Boolean = {
        this.synchronized {
            val name = pack.getText("name");
            val v = pack.get("policy");
            if (name == null || v == null) {
                return false;
            }
            val result = GroupFileHandler.addAccountGroup(groupFile, name, v.asInstanceOf[MapValue]);
            if (result) {
                groupPolicyMap.put(name, v.asInstanceOf[MapValue]);
                lastModifiedGroupFile = groupFile.lastModified();
            }
            return result;
        }
    }
    def editGroupPolicy(pack: MapPack): Boolean = {
        this.synchronized {
            val result = GroupFileHandler.editGroupPolicy(groupFile, pack);
            if (result) {
                loadGroupFile();
            }
            return result;
        }
    }
    def avaliableId(id: String): Boolean = {
        return accountMap.containsKey(id) == false;
    }
    def getAccount(id: String): Account = {
        return accountMap.get(id);
    }
    def getGroupPolicy(groupName: String): MapValue = {
        return groupPolicyMap.get(groupName);
    }
    def readAccountGroup(): Array[Byte] = {
        return FileUtil.readAll(groupFile);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy