diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/lib/auth.ts | 29 | ||||
-rw-r--r-- | server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js | 69 | ||||
-rw-r--r-- | server/tests/plugins/id-and-pass-auth.ts | 14 |
3 files changed, 110 insertions, 2 deletions
diff --git a/server/lib/auth.ts b/server/lib/auth.ts index c47ec62d0..5a6dd9dec 100644 --- a/server/lib/auth.ts +++ b/server/lib/auth.ts | |||
@@ -7,6 +7,7 @@ import { logger } from '@server/helpers/logger' | |||
7 | import { UserRole } from '@shared/models' | 7 | import { UserRole } from '@shared/models' |
8 | import { revokeToken } from '@server/lib/oauth-model' | 8 | import { revokeToken } from '@server/lib/oauth-model' |
9 | import { OAuthTokenModel } from '@server/models/oauth/oauth-token' | 9 | import { OAuthTokenModel } from '@server/models/oauth/oauth-token' |
10 | import { isUserUsernameValid, isUserRoleValid, isUserDisplayNameValid } from '@server/helpers/custom-validators/users' | ||
10 | 11 | ||
11 | const oAuthServer = new OAuthServer({ | 12 | const oAuthServer = new OAuthServer({ |
12 | useErrorHandler: true, | 13 | useErrorHandler: true, |
@@ -120,10 +121,12 @@ async function proxifyPasswordGrant (req: express.Request, res: express.Response | |||
120 | 121 | ||
121 | for (const pluginAuth of pluginAuths) { | 122 | for (const pluginAuth of pluginAuths) { |
122 | const authOptions = pluginAuth.registerAuthOptions | 123 | const authOptions = pluginAuth.registerAuthOptions |
124 | const authName = authOptions.authName | ||
125 | const npmName = pluginAuth.npmName | ||
123 | 126 | ||
124 | logger.debug( | 127 | logger.debug( |
125 | 'Using auth method %s of plugin %s to login %s with weight %d.', | 128 | 'Using auth method %s of plugin %s to login %s with weight %d.', |
126 | authOptions.authName, pluginAuth.npmName, loginOptions.id, authOptions.getWeight() | 129 | authName, npmName, loginOptions.id, authOptions.getWeight() |
127 | ) | 130 | ) |
128 | 131 | ||
129 | try { | 132 | try { |
@@ -131,9 +134,31 @@ async function proxifyPasswordGrant (req: express.Request, res: express.Response | |||
131 | if (loginResult) { | 134 | if (loginResult) { |
132 | logger.info( | 135 | logger.info( |
133 | 'Login success with auth method %s of plugin %s for %s.', | 136 | 'Login success with auth method %s of plugin %s for %s.', |
134 | authOptions.authName, pluginAuth.npmName, loginOptions.id | 137 | authName, npmName, loginOptions.id |
135 | ) | 138 | ) |
136 | 139 | ||
140 | if (!isUserUsernameValid(loginResult.username)) { | ||
141 | logger.error('Auth method %s of plugin %s did not provide a valid username.', authName, npmName, { loginResult }) | ||
142 | continue | ||
143 | } | ||
144 | |||
145 | if (!loginResult.email) { | ||
146 | logger.error('Auth method %s of plugin %s did not provide a valid email.', authName, npmName, { loginResult }) | ||
147 | continue | ||
148 | } | ||
149 | |||
150 | // role is optional | ||
151 | if (loginResult.role && !isUserRoleValid(loginResult.role)) { | ||
152 | logger.error('Auth method %s of plugin %s did not provide a valid role.', authName, npmName, { loginResult }) | ||
153 | continue | ||
154 | } | ||
155 | |||
156 | // display name is optional | ||
157 | if (loginResult.displayName && !isUserDisplayNameValid(loginResult.displayName)) { | ||
158 | logger.error('Auth method %s of plugin %s did not provide a valid display name.', authName, npmName, { loginResult }) | ||
159 | continue | ||
160 | } | ||
161 | |||
137 | res.locals.bypassLogin = { | 162 | res.locals.bypassLogin = { |
138 | bypass: true, | 163 | bypass: true, |
139 | pluginName: pluginAuth.npmName, | 164 | pluginName: pluginAuth.npmName, |
diff --git a/server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js b/server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js index 372f3fa0c..caa6a7ccd 100644 --- a/server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js +++ b/server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js | |||
@@ -23,6 +23,75 @@ async function register ({ | |||
23 | return null | 23 | return null |
24 | } | 24 | } |
25 | }) | 25 | }) |
26 | |||
27 | registerIdAndPassAuth({ | ||
28 | authName: 'ward-auth', | ||
29 | |||
30 | getWeight: () => 5, | ||
31 | |||
32 | login (body) { | ||
33 | if (body.id === 'ward') { | ||
34 | return Promise.resolve({ | ||
35 | username: 'ward-42', | ||
36 | email: 'ward@example.com' | ||
37 | }) | ||
38 | } | ||
39 | |||
40 | return null | ||
41 | } | ||
42 | }) | ||
43 | |||
44 | registerIdAndPassAuth({ | ||
45 | authName: 'kiros-auth', | ||
46 | |||
47 | getWeight: () => 5, | ||
48 | |||
49 | login (body) { | ||
50 | if (body.id === 'kiros') { | ||
51 | return Promise.resolve({ | ||
52 | username: 'kiros', | ||
53 | email: 'kiros@example.com', | ||
54 | displayName: 'a'.repeat(5000) | ||
55 | }) | ||
56 | } | ||
57 | |||
58 | return null | ||
59 | } | ||
60 | }) | ||
61 | |||
62 | registerIdAndPassAuth({ | ||
63 | authName: 'raine-auth', | ||
64 | |||
65 | getWeight: () => 5, | ||
66 | |||
67 | login (body) { | ||
68 | if (body.id === 'raine') { | ||
69 | return Promise.resolve({ | ||
70 | username: 'raine', | ||
71 | email: 'raine@example.com', | ||
72 | role: 42 | ||
73 | }) | ||
74 | } | ||
75 | |||
76 | return null | ||
77 | } | ||
78 | }) | ||
79 | |||
80 | registerIdAndPassAuth({ | ||
81 | authName: 'ellone-auth', | ||
82 | |||
83 | getWeight: () => 5, | ||
84 | |||
85 | login (body) { | ||
86 | if (body.id === 'ellone') { | ||
87 | return Promise.resolve({ | ||
88 | username: 'ellone' | ||
89 | }) | ||
90 | } | ||
91 | |||
92 | return null | ||
93 | } | ||
94 | }) | ||
26 | } | 95 | } |
27 | 96 | ||
28 | async function unregister () { | 97 | async function unregister () { |
diff --git a/server/tests/plugins/id-and-pass-auth.ts b/server/tests/plugins/id-and-pass-auth.ts index caf65b55f..c6382435d 100644 --- a/server/tests/plugins/id-and-pass-auth.ts +++ b/server/tests/plugins/id-and-pass-auth.ts | |||
@@ -151,6 +151,20 @@ describe('Test id and pass auth plugins', function () { | |||
151 | await getMyUserInformation(server.url, lagunaAccessToken, 401) | 151 | await getMyUserInformation(server.url, lagunaAccessToken, 401) |
152 | }) | 152 | }) |
153 | 153 | ||
154 | it('Should reject an invalid username, email, role or display name', async function () { | ||
155 | await userLogin(server, { username: 'ward', password: 'ward password' }, 400) | ||
156 | await waitUntilLog(server, 'valid username') | ||
157 | |||
158 | await userLogin(server, { username: 'kiros', password: 'kiros password' }, 400) | ||
159 | await waitUntilLog(server, 'valid display name') | ||
160 | |||
161 | await userLogin(server, { username: 'raine', password: 'raine password' }, 400) | ||
162 | await waitUntilLog(server, 'valid role') | ||
163 | |||
164 | await userLogin(server, { username: 'ellone', password: 'elonne password' }, 400) | ||
165 | await waitUntilLog(server, 'valid email') | ||
166 | }) | ||
167 | |||
154 | it('Should uninstall the plugin one and do not login existing Crash', async function () { | 168 | it('Should uninstall the plugin one and do not login existing Crash', async function () { |
155 | await uninstallPlugin({ | 169 | await uninstallPlugin({ |
156 | url: server.url, | 170 | url: server.url, |