1/*
2 * Copyright 2008 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.mockftpserver.fake
17
18import org.mockftpserver.fake.CustomUserAccount
19import org.mockftpserver.fake.UserAccount
20import org.mockftpserver.fake.filesystem.FileEntry
21import org.mockftpserver.fake.filesystem.FileSystemEntry
22import org.mockftpserver.fake.filesystem.Permissions
23import org.mockftpserver.test.AbstractGroovyTest
24
25/**
26 * Tests for UserAccount
27 *
28 * @version $Revision$ - $Date$
29 *
30 * @author Chris Mair
31 */
32class UserAccountTest extends AbstractGroovyTest {
33
34    private static final USERNAME = "user123"
35    private static final PASSWORD = "password123"
36    private static final HOME_DIR = "/usr/user123"
37    private static final GROUP = 'group'
38
39    private UserAccount userAccount
40
41    void testConstructor() {
42        def acct = new UserAccount(USERNAME, PASSWORD, HOME_DIR)
43        assert acct.username == USERNAME
44        assert acct.password == PASSWORD
45        assert acct.homeDirectory == HOME_DIR
46    }
47
48    void testGetPrimaryGroup() {
49        assert userAccount.primaryGroup == UserAccount.DEFAULT_GROUP
50
51        userAccount.groups = ['abc']
52        assert userAccount.primaryGroup == 'abc'
53
54        userAccount.groups.add('def')
55        assert userAccount.primaryGroup == 'abc'
56
57        userAccount.groups = []
58        assert userAccount.primaryGroup == UserAccount.DEFAULT_GROUP
59    }
60
61    void testIsValidPassword() {
62        userAccount.username = USERNAME
63        userAccount.password = PASSWORD
64        assert userAccount.isValidPassword(PASSWORD)
65
66        assert !userAccount.isValidPassword("")
67        assert !userAccount.isValidPassword("wrong")
68        assert !userAccount.isValidPassword(null)
69    }
70
71    void testIsValidPassword_UsernameNullOrEmpty() {
72        userAccount.password = PASSWORD
73        shouldFailWithMessageContaining('username') { userAccount.isValidPassword(PASSWORD) }
74
75        userAccount.username = ''
76        shouldFailWithMessageContaining('username') { userAccount.isValidPassword(PASSWORD) }
77    }
78
79    void testIsValidPassword_OverrideComparePassword() {
80        def customUserAccount = new CustomUserAccount()
81        customUserAccount.username = USERNAME
82        customUserAccount.password = PASSWORD
83        println customUserAccount
84        assert customUserAccount.isValidPassword(PASSWORD) == false
85        assert customUserAccount.isValidPassword(PASSWORD + "123")
86    }
87
88    void testIsValidPassword_PasswordNotCheckedDuringValidation() {
89        userAccount.username = USERNAME
90        userAccount.password = PASSWORD
91        userAccount.passwordCheckedDuringValidation = false
92        assert userAccount.isValidPassword("wrong")
93    }
94
95    void testIsValid() {
96        assert !userAccount.valid
97        userAccount.homeDirectory = ""
98        assert !userAccount.valid
99        userAccount.homeDirectory = "/abc"
100        assert userAccount.valid
101    }
102
103    void testCanRead() {
104        // No file permissions - readable by all
105        testCanRead(USERNAME, GROUP, null, true)
106
107        // UserAccount has no username or group; use World permissions
108        testCanRead(USERNAME, GROUP, '------r--', true)
109        testCanRead(USERNAME, GROUP, 'rwxrwx-wx', false)
110
111        userAccount.username = USERNAME
112        userAccount.groups = [GROUP]
113
114        testCanRead(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
115        testCanRead(USERNAME, GROUP, '---------', false)    // NONE
116
117        testCanRead(USERNAME, null, 'r--------', true)      // User
118        testCanRead(USERNAME, null, '-wxrwxrwx', false)
119
120        testCanRead(null, GROUP, '---r-----', true)         // Group
121        testCanRead(null, GROUP, 'rwx-wxrwx', false)
122
123        testCanRead(null, null, '------r--', true)          // World
124        testCanRead(null, null, 'rwxrwx-wx', false)
125    }
126
127    void testCanWrite() {
128        // No file permissions - writable by all
129        testCanWrite(USERNAME, GROUP, null, true)
130
131        // UserAccount has no username or group; use World permissions
132        testCanWrite(USERNAME, GROUP, '-------w-', true)
133        testCanWrite(USERNAME, GROUP, 'rwxrwxr-x', false)
134
135        userAccount.username = USERNAME
136        userAccount.groups = [GROUP]
137
138        testCanWrite(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
139        testCanWrite(USERNAME, GROUP, '---------', false)    // NONE
140
141        testCanWrite(USERNAME, null, '-w-------', true)      // User
142        testCanWrite(USERNAME, null, 'r-xrwxrwx', false)
143
144        testCanWrite(null, GROUP, '----w----', true)         // Group
145        testCanWrite(null, GROUP, 'rwxr-xrwx', false)
146
147        testCanWrite(null, null, '-------w-', true)          // World
148        testCanWrite(null, null, 'rwxrwxr-x', false)
149    }
150
151    void testCanExecute() {
152        // No file permissions - executable by all
153        testCanExecute(USERNAME, GROUP, null, true)
154
155        // UserAccount has no username or group; use World permissions
156        testCanExecute(USERNAME, GROUP, '--------x', true)
157        testCanExecute(USERNAME, GROUP, 'rwxrwxrw-', false)
158
159        userAccount.username = USERNAME
160        userAccount.groups = [GROUP]
161
162        testCanExecute(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
163        testCanExecute(USERNAME, GROUP, '---------', false)    // NONE
164
165        testCanExecute(USERNAME, null, '--x------', true)      // User
166        testCanExecute(USERNAME, null, 'rw-rwxrwx', false)
167
168        testCanExecute(null, GROUP, '-----x---', true)         // Group
169        testCanExecute(null, GROUP, 'rwxrw-rwx', false)
170
171        testCanExecute(null, null, '--------x', true)          // World
172        testCanExecute(null, null, 'rwxrwxrw-', false)
173    }
174
175    void testDefaultPermissions() {
176        assert userAccount.defaultPermissionsForNewFile == new Permissions('rw-rw-rw-')
177        assert userAccount.defaultPermissionsForNewDirectory == Permissions.ALL
178    }
179
180    //--------------------------------------------------------------------------
181    // Helper Methods
182    //--------------------------------------------------------------------------
183
184    private void testCanRead(owner, group, permissionsString, expectedResult) {
185        def file = createFileEntry(owner, permissionsString, group)
186        assert userAccount.canRead(file) == expectedResult, file
187    }
188
189    private void testCanWrite(owner, group, permissionsString, expectedResult) {
190        def file = createFileEntry(owner, permissionsString, group)
191        assert userAccount.canWrite(file) == expectedResult, file
192    }
193
194    private void testCanExecute(owner, group, permissionsString, expectedResult) {
195        def file = createFileEntry(owner, permissionsString, group)
196        assert userAccount.canExecute(file) == expectedResult, file
197    }
198
199    private FileSystemEntry createFileEntry(owner, permissionsString, group) {
200        def permissions = permissionsString ? new Permissions(permissionsString) : null
201        return new FileEntry(path: '', owner: owner, group: group, permissions: permissions)
202    }
203
204    void setUp() {
205        super.setUp()
206        userAccount = new UserAccount()
207    }
208}