3
3
4
4
import { Callback , IPluginAuth , Logger , PluginOptions , RemoteUser , PackageAccess } from '@verdaccio/types' ;
5
5
import { getInternalError , getUnauthorized , getForbidden } from '@verdaccio/commons-api' ;
6
- import { UserDataGroups } from './authcache' ;
7
-
8
6
import Gitlab from 'gitlab' ;
7
+
8
+ import { UserDataGroups } from './authcache' ;
9
9
import { AuthCache , UserData } from './authcache' ;
10
10
11
- export type VerdaccioGitlabAccessLevel =
12
- '$guest' |
13
- '$reporter' |
14
- '$developer' |
15
- '$maintainer' |
16
- '$owner' ;
11
+ export type VerdaccioGitlabAccessLevel = '$guest' | '$reporter' | '$developer' | '$maintainer' | '$owner' ;
17
12
18
13
export type VerdaccioGitlabConfig = {
19
- url : string ,
14
+ url : string ;
20
15
authCache ?: {
21
- enabled ?: boolean ,
22
- ttl ?: number
23
- } ,
24
- legacy_mode ?: boolean ,
25
- publish ?: VerdaccioGitlabAccessLevel
16
+ enabled ?: boolean ;
17
+ ttl ?: number ;
18
+ } ;
19
+ legacy_mode ?: boolean ;
20
+ publish ?: VerdaccioGitlabAccessLevel ;
26
21
} ;
27
22
28
23
export interface VerdaccioGitlabPackageAccess extends PackageAccess {
29
- name ?: string ,
30
- gitlab ?: boolean
31
- } ;
24
+ name ?: string ;
25
+ gitlab ?: boolean ;
26
+ }
32
27
33
28
const ACCESS_LEVEL_MAPPING = {
34
29
$guest : 10 ,
35
30
$reporter : 20 ,
36
31
$developer : 30 ,
37
32
$maintainer : 40 ,
38
- $owner : 50
33
+ $owner : 50 ,
39
34
} ;
40
35
41
36
// List of verdaccio builtin levels that map to anonymous access
42
- const BUILTIN_ACCESS_LEVEL_ANONYMOUS = [ '$anonymous' , '$all' ] ;
37
+ const BUILTIN_ACCESS_LEVEL_ANONYMOUS = [ '$anonymous' , '$all' ] ;
43
38
44
39
// Level to apply on 'allow_access' calls when a package definition does not define one
45
- const DEFAULT_ALLOW_ACCESS_LEVEL = [ '$all' ] ;
46
-
40
+ const DEFAULT_ALLOW_ACCESS_LEVEL = [ '$all' ] ;
47
41
48
42
export interface VerdaccioGitLabPlugin extends IPluginAuth < VerdaccioGitlabConfig > {
49
43
authCache : AuthCache ;
50
44
}
51
45
52
-
53
46
export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
54
47
options : PluginOptions < VerdaccioGitlabConfig > ;
55
48
config : VerdaccioGitlabConfig ;
@@ -104,53 +97,58 @@ export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
104
97
105
98
const GitlabAPI = new Gitlab ( {
106
99
url : this . config . url ,
107
- token : password
100
+ token : password ,
108
101
} ) ;
109
102
110
- GitlabAPI . Users . current ( ) . then ( response => {
111
- if ( user !== response . username ) {
112
- return cb ( getForbidden ( 'wrong gitlab username' ) ) ;
113
- }
114
-
115
- const publishLevelId = ACCESS_LEVEL_MAPPING [ this . publishLevel ] ;
116
-
117
- // Set the groups of an authenticated user, in normal mode:
118
- // - for access, depending on the package settings in verdaccio
119
- // - for publish, the logged in user id and all the groups they can reach as configured with access level `$auth.gitlab.publish`
120
- //
121
- // In legacy mode, the groups are:
122
- // - for access, depending on the package settings in verdaccio
123
- // - for publish, the logged in user id and all the groups they can reach as fixed `$auth.gitlab.publish` = `$owner`
124
- const gitlabPublishQueryParams = this . config . legacy_mode ? { owned : true } : { min_access_level : publishLevelId } ;
125
- // @ts -ignore
126
- this . logger . trace ( '[gitlab] querying gitlab user groups with params:' , gitlabPublishQueryParams ) ;
127
-
128
- const groupsPromise = GitlabAPI . Groups . all ( gitlabPublishQueryParams ) . then ( groups => {
129
- return groups . filter ( group => group . path === group . full_path ) . map ( group => group . path ) ;
130
- } ) ;
131
-
132
- const projectsPromise = GitlabAPI . Projects . all ( gitlabPublishQueryParams ) . then ( projects => {
133
- return projects . map ( project => project . path_with_namespace ) ;
134
- } ) ;
135
-
136
- Promise . all ( [ groupsPromise , projectsPromise ] ) . then ( ( [ groups , projectGroups ] ) => {
137
- const realGroups = [ user , ...groups , ...projectGroups ] ;
138
- this . _setCachedUserGroups ( user , password , { publish : realGroups } ) ;
103
+ GitlabAPI . Users . current ( )
104
+ . then ( response => {
105
+ if ( user !== response . username ) {
106
+ return cb ( getForbidden ( 'wrong gitlab username' ) ) ;
107
+ }
139
108
140
- this . logger . info ( `[gitlab] user: ${ user } successfully authenticated` ) ;
109
+ const publishLevelId = ACCESS_LEVEL_MAPPING [ this . publishLevel ] ;
110
+
111
+ // Set the groups of an authenticated user, in normal mode:
112
+ // - for access, depending on the package settings in verdaccio
113
+ // - for publish, the logged in user id and all the groups they can reach as configured with access level `$auth.gitlab.publish`
114
+ //
115
+ // In legacy mode, the groups are:
116
+ // - for access, depending on the package settings in verdaccio
117
+ // - for publish, the logged in user id and all the groups they can reach as fixed `$auth.gitlab.publish` = `$owner`
118
+ const gitlabPublishQueryParams = this . config . legacy_mode
119
+ ? { owned : true }
120
+ : { min_access_level : publishLevelId } ;
141
121
// @ts -ignore
142
- this . logger . debug ( `[gitlab] user: ${ user } , with groups:` , realGroups ) ;
143
-
144
- return cb ( null , realGroups ) ;
145
- } ) . catch ( error => {
146
- this . logger . error ( `[gitlab] user: ${ user } error querying gitlab: ${ error } ` ) ;
122
+ this . logger . trace ( '[gitlab] querying gitlab user groups with params:' , gitlabPublishQueryParams ) ;
123
+
124
+ const groupsPromise = GitlabAPI . Groups . all ( gitlabPublishQueryParams ) . then ( groups => {
125
+ return groups . filter ( group => group . path === group . full_path ) . map ( group => group . path ) ;
126
+ } ) ;
127
+
128
+ const projectsPromise = GitlabAPI . Projects . all ( gitlabPublishQueryParams ) . then ( projects => {
129
+ return projects . map ( project => project . path_with_namespace ) ;
130
+ } ) ;
131
+
132
+ Promise . all ( [ groupsPromise , projectsPromise ] )
133
+ . then ( ( [ groups , projectGroups ] ) => {
134
+ const realGroups = [ user , ...groups , ...projectGroups ] ;
135
+ this . _setCachedUserGroups ( user , password , { publish : realGroups } ) ;
136
+
137
+ this . logger . info ( `[gitlab] user: ${ user } successfully authenticated` ) ;
138
+ // @ts -ignore
139
+ this . logger . debug ( `[gitlab] user: ${ user } , with groups:` , realGroups ) ;
140
+
141
+ return cb ( null , realGroups ) ;
142
+ } )
143
+ . catch ( error => {
144
+ this . logger . error ( `[gitlab] user: ${ user } error querying gitlab: ${ error } ` ) ;
145
+ return cb ( getUnauthorized ( 'error authenticating user' ) ) ;
146
+ } ) ;
147
+ } )
148
+ . catch ( error => {
149
+ this . logger . error ( `[gitlab] user: ${ user } error querying gitlab user data: ${ error . message || { } } ` ) ;
147
150
return cb ( getUnauthorized ( 'error authenticating user' ) ) ;
148
151
} ) ;
149
-
150
- } ) . catch ( error => {
151
- this . logger . error ( `[gitlab] user: ${ user } error querying gitlab user data: ${ error . message || { } } ` ) ;
152
- return cb ( getUnauthorized ( 'error authenticating user' ) ) ;
153
- } ) ;
154
152
}
155
153
156
154
adduser ( user : string , password : string , cb : Callback ) {
@@ -166,12 +164,14 @@ export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
166
164
allow_access ( user : RemoteUser , _package : VerdaccioGitlabPackageAccess & PackageAccess , cb : Callback ) {
167
165
if ( ! _package . gitlab ) return cb ( null , false ) ;
168
166
169
- const packageAccess = ( _package . access && _package . access . length > 0 ) ? _package . access : DEFAULT_ALLOW_ACCESS_LEVEL ;
167
+ const packageAccess = _package . access && _package . access . length > 0 ? _package . access : DEFAULT_ALLOW_ACCESS_LEVEL ;
170
168
171
- if ( user . name !== undefined ) { // successfully authenticated
169
+ if ( user . name !== undefined ) {
170
+ // successfully authenticated
172
171
this . logger . debug ( `[gitlab] allow user: ${ user . name } authenticated access to package: ${ _package . name } ` ) ;
173
172
return cb ( null , true ) ;
174
- } else { // unauthenticated
173
+ } else {
174
+ // unauthenticated
175
175
if ( BUILTIN_ACCESS_LEVEL_ANONYMOUS . some ( level => packageAccess . includes ( level ) ) ) {
176
176
this . logger . debug ( `[gitlab] allow anonymous access to package: ${ _package . name } ` ) ;
177
177
return cb ( null , true ) ;
@@ -185,13 +185,16 @@ export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
185
185
allow_publish ( user : RemoteUser , _package : VerdaccioGitlabPackageAccess & PackageAccess , cb : Callback ) {
186
186
if ( ! _package . gitlab ) return cb ( null , false ) ;
187
187
188
- let packageScopePermit = false ;
188
+ const packageScopePermit = false ;
189
189
let packagePermit = false ;
190
190
// Only allow to publish packages when:
191
191
// - the package has exactly the same name as one of the user groups, or
192
192
// - the package scope is the same as one of the user groups
193
- for ( let real_group of user . real_groups ) { // jscs:ignore requireCamelCaseOrUpperCaseIdentifiers
194
- this . logger . trace ( `[gitlab] publish: checking group: ${ real_group } for user: ${ user . name || '' } and package: ${ _package . name } ` ) ;
193
+ for ( const real_group of user . real_groups ) {
194
+ // jscs:ignore requireCamelCaseOrUpperCaseIdentifiers
195
+ this . logger . trace (
196
+ `[gitlab] publish: checking group: ${ real_group } for user: ${ user . name || '' } and package: ${ _package . name } `
197
+ ) ;
195
198
196
199
if ( this . _matchGroupWithPackage ( real_group , _package . name as string ) ) {
197
200
packagePermit = true ;
@@ -201,7 +204,9 @@ export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
201
204
202
205
if ( packagePermit || packageScopePermit ) {
203
206
const perm = packagePermit ? 'package-name' : 'package-scope' ;
204
- this . logger . debug ( `[gitlab] user: ${ user . name || '' } allowed to publish package: ${ _package . name } based on ${ perm } ` ) ;
207
+ this . logger . debug (
208
+ `[gitlab] user: ${ user . name || '' } allowed to publish package: ${ _package . name } based on ${ perm } `
209
+ ) ;
205
210
return cb ( null , true ) ;
206
211
} else {
207
212
this . logger . debug ( `[gitlab] user: ${ user . name || '' } denied from publishing package: ${ _package . name } ` ) ;
@@ -213,7 +218,7 @@ export default class VerdaccioGitLab implements VerdaccioGitLabPlugin {
213
218
214
219
_matchGroupWithPackage ( real_group : string , package_name : string ) : boolean {
215
220
if ( real_group === package_name ) {
216
- return true
221
+ return true ;
217
222
}
218
223
219
224
if ( package_name . indexOf ( '@' ) === 0 ) {
0 commit comments