001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.operations.daemon;
019
020import io.undertow.security.idm.Account;
021import io.undertow.security.idm.Credential;
022import io.undertow.security.idm.IdentityManager;
023import io.undertow.security.idm.PasswordCredential;
024
025import java.security.Principal;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.HashMap;
029import java.util.List;
030import java.util.Map;
031import java.util.Set;
032
033import org.syncany.config.to.UserTO;
034
035/**
036 * A simple {@link IdentityManager} implementation, that just takes a map of users 
037 * to their password.
038 * 
039 * @see <a href="https://github.com/undertow-io/undertow/blob/d160f7c44951c25186595e4755c45659396d057c/examples/src/main/java/io/undertow/examples/security/basic/MapIdentityManager.java">Original implementation (from Undertow)</a>
040 * @author Stuart Douglas
041 */
042public class MapIdentityManager implements IdentityManager {
043        private final Map<String, char[]> users;
044
045        public MapIdentityManager(List<UserTO> users) {
046                this.users = new HashMap<String, char[]>();
047
048                for (UserTO user : users) {
049                        this.users.put(user.getUsername(), user.getPassword().toCharArray());
050                }
051        }
052
053        @Override
054        public Account verify(Account account) {
055                // An existing account so for testing assume still valid.
056                return account;
057        }
058
059        @Override
060        public Account verify(String id, Credential credential) {
061                Account account = getAccount(id);
062                if (account != null && verifyCredential(account, credential)) {
063                        return account;
064                }
065
066                return null;
067        }
068
069        @Override
070        public Account verify(Credential credential) {
071                throw new RuntimeException("Not implemented.");
072        }
073
074        private boolean verifyCredential(Account account, Credential credential) {
075                if (credential instanceof PasswordCredential) {
076                        char[] password = ((PasswordCredential) credential).getPassword();
077                        char[] expectedPassword = users.get(account.getPrincipal().getName());
078
079                        return Arrays.equals(password, expectedPassword);
080                }
081                return false;
082        }
083
084        private Account getAccount(final String id) {
085                if (users.containsKey(id)) {
086                        return new Account() {
087                                private final Principal principal = new Principal() {
088                                        @Override
089                                        public String getName() {
090                                                return id;
091                                        }
092                                };
093
094                                @Override
095                                public Principal getPrincipal() {
096                                        return principal;
097                                }
098
099                                @Override
100                                public Set<String> getRoles() {
101                                        return Collections.emptySet();
102                                }
103                        };
104                }
105                
106                return null;
107        }
108}