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.filesystem.FileEntry
19import org.mockftpserver.fake.filesystem.FileSystemEntry
20import org.mockftpserver.fake.filesystem.Permissions
21import org.mockftpserver.test.AbstractGroovyTestCase
22
23/**
24 * Tests for UserAccount
25 *
26 * @version $Revision$ - $Date$
27 *
28 * @author Chris Mair
29 */
30class UserAccountTest extends AbstractGroovyTestCase {
31
32    private static final USERNAME = "user123"
33    private static final PASSWORD = "password123"
34    private static final HOME_DIR = "/usr/user123"
35    private static final GROUP = 'group'
36
37    private UserAccount userAccount
38
39    void testConstructor() {
40        def acct = new UserAccount(USERNAME, PASSWORD, HOME_DIR)
41        assert acct.username == USERNAME
42        assert acct.password == PASSWORD
43        assert acct.homeDirectory == HOME_DIR
44    }
45
46    void testGetPrimaryGroup() {
47        assert userAccount.primaryGroup == UserAccount.DEFAULT_GROUP
48
49        userAccount.groups = ['abc']
50        assert userAccount.primaryGroup == 'abc'
51
52        userAccount.groups.add('def')
53        assert userAccount.primaryGroup == 'abc'
54
55        userAccount.groups = []
56        assert userAccount.primaryGroup == UserAccount.DEFAULT_GROUP
57    }
58
59    void testIsValidPassword() {
60        userAccount.username = USERNAME
61        userAccount.password = PASSWORD
62        assert userAccount.isValidPassword(PASSWORD)
63
64        assert !userAccount.isValidPassword("")
65        assert !userAccount.isValidPassword("wrong")
66        assert !userAccount.isValidPassword(null)
67    }
68
69    void testIsValidPassword_UsernameNullOrEmpty() {
70        userAccount.password = PASSWORD
71        shouldFailWithMessageContaining('username') { userAccount.isValidPassword(PASSWORD) }
72
73        userAccount.username = ''
74        shouldFailWithMessageContaining('username') { userAccount.isValidPassword(PASSWORD) }
75    }
76
77    void testIsValidPassword_OverrideComparePassword() {
78        def customUserAccount = new CustomUserAccount()
79        customUserAccount.username = USERNAME
80        customUserAccount.password = PASSWORD
81        println customUserAccount
82        assert customUserAccount.isValidPassword(PASSWORD) == false
83        assert customUserAccount.isValidPassword(PASSWORD + "123")
84    }
85
86    void testIsValidPassword_PasswordNotCheckedDuringValidation() {
87        userAccount.username = USERNAME
88        userAccount.password = PASSWORD
89        userAccount.passwordCheckedDuringValidation = false
90        assert userAccount.isValidPassword("wrong")
91    }
92
93    void testIsValid() {
94        assert !userAccount.valid
95        userAccount.homeDirectory = ""
96        assert !userAccount.valid
97        userAccount.homeDirectory = "/abc"
98        assert userAccount.valid
99    }
100
101    void testCanRead() {
102        // No file permissions - readable by all
103        testCanRead(USERNAME, GROUP, null, true)
104
105        // UserAccount has no username or group; use World permissions
106        testCanRead(USERNAME, GROUP, '------r--', true)
107        testCanRead(USERNAME, GROUP, 'rwxrwx-wx', false)
108
109        userAccount.username = USERNAME
110        userAccount.groups = [GROUP]
111
112        testCanRead(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
113        testCanRead(USERNAME, GROUP, '---------', false)    // NONE
114
115        testCanRead(USERNAME, null, 'r--------', true)      // User
116        testCanRead(USERNAME, null, '-wxrwxrwx', false)
117
118        testCanRead(null, GROUP, '---r-----', true)         // Group
119        testCanRead(null, GROUP, 'rwx-wxrwx', false)
120
121        testCanRead(null, null, '------r--', true)          // World
122        testCanRead(null, null, 'rwxrwx-wx', false)
123    }
124
125    void testCanWrite() {
126        // No file permissions - writable by all
127        testCanWrite(USERNAME, GROUP, null, true)
128
129        // UserAccount has no username or group; use World permissions
130        testCanWrite(USERNAME, GROUP, '-------w-', true)
131        testCanWrite(USERNAME, GROUP, 'rwxrwxr-x', false)
132
133        userAccount.username = USERNAME
134        userAccount.groups = [GROUP]
135
136        testCanWrite(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
137        testCanWrite(USERNAME, GROUP, '---------', false)    // NONE
138
139        testCanWrite(USERNAME, null, '-w-------', true)      // User
140        testCanWrite(USERNAME, null, 'r-xrwxrwx', false)
141
142        testCanWrite(null, GROUP, '----w----', true)         // Group
143        testCanWrite(null, GROUP, 'rwxr-xrwx', false)
144
145        testCanWrite(null, null, '-------w-', true)          // World
146        testCanWrite(null, null, 'rwxrwxr-x', false)
147    }
148
149    void testCanExecute() {
150        // No file permissions - executable by all
151        testCanExecute(USERNAME, GROUP, null, true)
152
153        // UserAccount has no username or group; use World permissions
154        testCanExecute(USERNAME, GROUP, '--------x', true)
155        testCanExecute(USERNAME, GROUP, 'rwxrwxrw-', false)
156
157        userAccount.username = USERNAME
158        userAccount.groups = [GROUP]
159
160        testCanExecute(USERNAME, GROUP, 'rwxrwxrwx', true)     // ALL
161        testCanExecute(USERNAME, GROUP, '---------', false)    // NONE
162
163        testCanExecute(USERNAME, null, '--x------', true)      // User
164        testCanExecute(USERNAME, null, 'rw-rwxrwx', false)
165
166        testCanExecute(null, GROUP, '-----x---', true)         // Group
167        testCanExecute(null, GROUP, 'rwxrw-rwx', false)
168
169        testCanExecute(null, null, '--------x', true)          // World
170        testCanExecute(null, null, 'rwxrwxrw-', false)
171    }
172
173    void testDefaultPermissions() {
174        assert userAccount.defaultPermissionsForNewFile == new Permissions('rw-rw-rw-')
175        assert userAccount.defaultPermissionsForNewDirectory == Permissions.ALL
176    }
177
178    //--------------------------------------------------------------------------
179    // Helper Methods
180    //--------------------------------------------------------------------------
181
182    private void testCanRead(owner, group, permissionsString, expectedResult) {
183        def file = createFileEntry(owner, permissionsString, group)
184        assert userAccount.canRead(file) == expectedResult, file
185    }
186
187    private void testCanWrite(owner, group, permissionsString, expectedResult) {
188        def file = createFileEntry(owner, permissionsString, group)
189        assert userAccount.canWrite(file) == expectedResult, file
190    }
191
192    private void testCanExecute(owner, group, permissionsString, expectedResult) {
193        def file = createFileEntry(owner, permissionsString, group)
194        assert userAccount.canExecute(file) == expectedResult, file
195    }
196
197    private FileSystemEntry createFileEntry(owner, permissionsString, group) {
198        def permissions = permissionsString ? new Permissions(permissionsString) : null
199        return new FileEntry(path: '', owner: owner, group: group, permissions: permissions)
200    }
201
202    void setUp() {
203        super.setUp()
204        userAccount = new UserAccount()
205    }
206}