001package org.apache.maven.wagon.providers.ftp;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.commons.io.FileUtils;
027import org.apache.ftpserver.FtpServer;
028import org.apache.ftpserver.FtpServerFactory;
029import org.apache.ftpserver.ftplet.Authority;
030import org.apache.ftpserver.ftplet.UserManager;
031import org.apache.ftpserver.listener.Listener;
032import org.apache.ftpserver.listener.ListenerFactory;
033import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
034import org.apache.ftpserver.usermanager.impl.BaseUser;
035import org.apache.ftpserver.usermanager.impl.WritePermission;
036import org.apache.maven.wagon.FileTestUtils;
037import org.apache.maven.wagon.StreamingWagonTestCase;
038import org.apache.maven.wagon.Wagon;
039import org.apache.maven.wagon.authentication.AuthenticationException;
040import org.apache.maven.wagon.authentication.AuthenticationInfo;
041import org.apache.maven.wagon.repository.Repository;
042import org.apache.maven.wagon.resource.Resource;
043
044/**
045 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
046 *
047 */
048public class FtpWagonTest
049    extends StreamingWagonTestCase
050{
051    private FtpServer server;
052    
053    private int testRepositoryPort;
054    
055    protected String getProtocol()
056    {
057        return "ftp";
058    }
059    
060    protected int getTestRepositoryPort() {
061        return testRepositoryPort;
062    }
063
064    protected void setupWagonTestingFixtures()
065        throws Exception
066    {
067        File ftpHomeDir = getRepositoryDirectory();
068        if ( !ftpHomeDir.exists() )
069        {
070            ftpHomeDir.mkdirs();
071        }
072
073        if ( server == null )
074        {
075            FtpServerFactory serverFactory = new FtpServerFactory();
076
077            ListenerFactory factory = new ListenerFactory();
078
079            // set the port of the listener
080            factory.setPort( 0 );
081            
082            // replace the default listener
083            Listener defaultListener = factory.createListener();
084            serverFactory.addListener("default", defaultListener );
085
086            PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
087            UserManager um = userManagerFactory.createUserManager();
088
089            BaseUser user = new BaseUser();
090            user.setName("admin");
091            user.setPassword("admin");
092
093            List<Authority> authorities = new ArrayList<Authority>();
094            authorities.add( new WritePermission() );
095
096            user.setAuthorities( authorities );
097
098            user.setHomeDirectory( ftpHomeDir.getAbsolutePath() );
099
100
101            um.save(user);
102
103            serverFactory.setUserManager( um );
104
105            server = serverFactory.createServer();
106
107            // start the server
108            server.start();
109
110            testRepositoryPort = defaultListener.getPort();
111        }
112    }
113
114    protected void createDirectory( Wagon wagon, String resourceToCreate, String dirName )
115        throws Exception
116    {
117        super.createDirectory( wagon, resourceToCreate, dirName );
118
119        getRepositoryDirectory().mkdirs();
120    }
121
122    protected void tearDownWagonTestingFixtures()
123        throws Exception
124    {
125        server.stop();
126        server = null;
127    }
128
129    protected String getTestRepositoryUrl()
130    {
131        return "ftp://localhost:" + getTestRepositoryPort();
132    }
133
134    public AuthenticationInfo getAuthInfo()
135    {
136        AuthenticationInfo authInfo = new AuthenticationInfo();
137
138        authInfo.setUserName( "admin" );
139
140        authInfo.setPassword( "admin" );
141
142        return authInfo;
143    }
144
145    protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
146    {
147        File file = new File( getRepositoryDirectory(), resource.getName() );
148
149        // granularity for FTP is minutes
150        return ( file.lastModified() / 60000 ) * 60000;
151    }
152
153    private File getRepositoryDirectory()
154    {
155        return getTestFile( "target/test-output/local-repository" );
156    }
157
158    public void testNoPassword()
159        throws Exception
160    {
161        AuthenticationInfo authenticationInfo = new AuthenticationInfo();
162        authenticationInfo.setUserName( "me" );
163        try
164        {
165            getWagon().connect( new Repository( "id", getTestRepositoryUrl() ), authenticationInfo );
166            fail();
167        }
168        catch ( AuthenticationException e )
169        {
170            assertTrue( true );
171        }
172    }
173
174    public void testDefaultUserName()
175        throws Exception
176    {
177        AuthenticationInfo authenticationInfo = new AuthenticationInfo();
178        authenticationInfo.setPassword( "secret" );
179        try
180        {
181            getWagon().connect( new Repository( "id", getTestRepositoryUrl() ), authenticationInfo );
182            fail();
183        }
184        catch ( AuthenticationException e )
185        {
186            assertEquals( System.getProperty( "user.name" ), authenticationInfo.getUserName() );
187        }
188    }
189
190    /**
191     * This is a unit test to show WAGON-265
192     */
193    public void testPutDirectoryCreation()
194        throws Exception
195    {
196        setupWagonTestingFixtures();
197
198        setupRepositories();
199
200        Wagon wagon = getWagon();
201
202        if ( wagon.supportsDirectoryCopy() )
203        {
204            // do the cleanup first
205            File destDir = new File( getRepositoryDirectory(), "dirExists" );
206            FileUtils.deleteDirectory( destDir );
207            destDir.mkdirs();
208            destDir = new File( destDir, "not_yet_existing/also_not" );
209
210            File sourceDir = new File( getRepositoryDirectory(), "testDirectory" );
211
212            FileUtils.deleteDirectory(sourceDir);
213            sourceDir.mkdir();
214
215            File testRes = new File( sourceDir, "test-resource-1.txt" );
216            testRes.createNewFile();
217
218            // This is the difference to our normal use case:
219            // the directory specified in the repo string doesn't yet exist!
220
221            testRepository.setUrl( testRepository.getUrl() + "/dirExists/not_yet_existing/also_not" );
222
223            wagon.connect( testRepository, getAuthInfo() );
224
225            wagon.putDirectory( sourceDir, "testDirectory" );
226
227            destFile = FileTestUtils.createUniqueFile(getName(), getName());
228
229            destFile.deleteOnExit();
230
231            wagon.get( "testDirectory/test-resource-1.txt", destFile );
232
233            wagon.disconnect();
234        }
235
236        tearDownWagonTestingFixtures();
237
238
239    }
240}