Skip to content
This repository was archived by the owner on Oct 5, 2020. It is now read-only.

Commit 9573883

Browse files
committed
#288: refinements, and test issues
1 parent 0a88ac3 commit 9573883

File tree

22 files changed

+254
-165
lines changed

22 files changed

+254
-165
lines changed

app/templates/deploy/app_specific.rb

Lines changed: 94 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,31 @@ class ServerConfig
4545
# # but it can be called without an environment
4646
# end
4747

48-
# Show-casing some useful overrides, as well as fixing some module doc permissions
48+
# Show-casing some useful overrides, as well as adjusting some module doc permissions
4949
alias_method :original_deploy_modules, :deploy_modules
5050
alias_method :original_deploy_rest, :deploy_rest
51+
alias_method :original_deploy, :deploy
5152
alias_method :original_clean, :clean
5253

54+
# Integrate deploy_packages into the Roxy deploy command
55+
def deploy
56+
what = ARGV.shift
57+
58+
case what
59+
when 'packages'
60+
deploy_packages
61+
else
62+
ARGV.unshift what
63+
original_deploy
64+
end
65+
end
66+
5367
def deploy_modules
54-
# Uncomment deploy_packages if you would like to use MLPM to deploy MLPM packages.
55-
# You can also move mlpm.json into src/ext/ and deploy plain modules (not REST extensions) that way.
68+
# Uncomment deploy_packages if you would like to use MLPM to deploy MLPM packages, and
69+
# include MLPM deploy in deploy modules to make sure MLPM depencencies are loaded first.
70+
71+
# Note: you can also move mlpm.json into src/ext/ and deploy plain modules (not REST extensions) that way.
72+
5673
#deploy_packages
5774
original_deploy_modules
5875
end
@@ -63,59 +80,68 @@ def deploy_packages
6380
-p #{ @ml_password } \
6481
-H #{ @properties['ml.server'] } \
6582
-P #{ @properties['ml.app-port'] }!
66-
fix_permissions(@properties["ml.modules-db"])
83+
change_permissions(@properties["ml.modules-db"])
6784
end
6885

6986
def deploy_rest
7087
original_deploy_rest
71-
fix_permissions(@properties["ml.modules-db"])
88+
change_permissions(@properties["ml.modules-db"])
7289
end
7390

74-
def fix_permissions(where)
75-
logger.info "Fixing permissions in #{where} for documents:"
76-
if where.include? "content"
77-
# This is useful to make sure alert configuration is accessible
78-
r = execute_query(
79-
%Q{
80-
xquery version "1.0-ml";
91+
# Permissions need to be changed for executable code that was not deployed via Roxy directly,
92+
# to make sure users with app-role can read and execute it. Typically applies to artifacts
93+
# installed via REST api, which only applies permissions for rest roles. Effectively also includes
94+
# MLPM, which uses REST api for deployment. It often also applies to artifacts installed with
95+
# custom code (via app_specific for instance), like alerts.
96+
def change_permissions(where)
97+
logger.info "Changing permissions in #{where} for:"
98+
r = execute_query(
99+
%Q{
100+
xquery version "1.0-ml";
81101
82-
for $uri in cts:uri-match("*alert*")
83-
return (
84-
$uri,
85-
xdmp:document-set-permissions($uri, (
86-
xdmp:permission("#{@properties["ml.app-name"]}-role", "read"),
87-
xdmp:permission("#{@properties["ml.app-name"]}-role", "update"),
88-
xdmp:permission("#{@properties["ml.app-name"]}-role", "execute")
89-
))
90-
)
91-
},
92-
{ :db_name => where }
93-
)
94-
else
95-
r = execute_query(
96-
%Q{
97-
xquery version "1.0-ml";
98-
99-
for $uri in cts:uris()
102+
let $new-permissions := (
103+
xdmp:permission("#{@properties["ml.app-name"]}-role", "read"),
104+
xdmp:permission("#{@properties["ml.app-name"]}-role", "update"),
105+
xdmp:permission("#{@properties["ml.app-name"]}-role", "execute")
106+
)
107+
108+
let $uris :=
109+
if (fn:contains(xdmp:database-name(xdmp:database()), "content")) then
110+
111+
(: This is to make sure all alert files are accessible :)
112+
cts:uri-match("*alert*")
113+
114+
else
115+
116+
(: This is to make sure all triggers, schemas, modules and REST extensions are accessible :)
117+
cts:uris()
118+
119+
let $fixes :=
120+
for $uri in $uris
121+
let $existing-permissions := xdmp:document-get-permissions($uri)
122+
123+
(: Only apply new permissions if really necessary (gives better logging too):)
100124
where not(ends-with($uri, "/"))
125+
and count($existing-permissions[fn:string(.) = $new-permissions/fn:string(.)]) ne 3
126+
101127
return (
102-
$uri,
103-
xdmp:document-set-permissions($uri, (
104-
xdmp:permission("#{@properties["ml.app-name"]}-role", "read"),
105-
xdmp:permission("#{@properties["ml.app-name"]}-role", "update"),
106-
xdmp:permission("#{@properties["ml.app-name"]}-role", "execute")
107-
))
108-
)
109-
},
110-
{ :db_name => where }
111-
)
112-
end
113-
128+
" " || $uri,
129+
xdmp:document-set-permissions($uri, $new-permissions)
130+
)
131+
return
132+
if ($fixes) then
133+
$fixes
134+
else
135+
" no changes needed.."
136+
},
137+
{ :db_name => where }
138+
)
114139
r.body = parse_json r.body
115140
logger.info r.body
116141
logger.info ""
117142
end
118-
143+
144+
# Integrate clean_collections into the Roxy clean command
119145
def clean
120146
what = ARGV.shift
121147

@@ -154,7 +180,7 @@ def clean_collections()
154180
# commands included into Roxy help. (ml -h)
155181
#
156182

157-
#class Help
183+
class Help
158184
# def self.app_specific
159185
# <<-DOC.strip_heredoc
160186
#
@@ -177,4 +203,27 @@ def clean_collections()
177203
# --whatever=value
178204
# DOC
179205
# end
180-
#end
206+
class <<self
207+
alias_method :original_deploy, :deploy
208+
209+
def deploy
210+
# Concatenate extra lines of documentation after original deploy
211+
# Help message (with a bit of indent to make it look better)
212+
original_deploy + " " +
213+
<<-DOC.strip_heredoc
214+
packages # deploys MLPM modules and REST extensions using MLPM to the app-port
215+
DOC
216+
end
217+
alias_method :original_clean, :clean
218+
219+
def clean
220+
# Concatenate extra lines of documentation after original clean
221+
# Help message (with a bit of indent to make it look better)
222+
original_clean + "\n " +
223+
<<-DOC.strip_heredoc
224+
collections WHAT
225+
# removes all files from (comma-separated list of) WHAT collection(s) in the content database
226+
DOC
227+
end
228+
end
229+
end

app/templates/gulpfile.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ gulp.task('build', ['optimize', 'images', 'fonts', 'statics', 'tinymce'], functi
275275

276276
var msg = {
277277
title: 'gulp build',
278-
subtitle: 'Deployed to the build folder',
279-
message: 'Running `gulp serve-dist`'
278+
subtitle: 'Deployed to the dist folder',
279+
message: 'Ready to run `gulp serve-dev` or `gulp serve-prod`'
280280
};
281281
log(msg);
282282
notify(msg);
@@ -544,9 +544,9 @@ function init(env, done) {
544544
return answers.mlVersion < 8;
545545
}},
546546
{type: 'input', name: 'nodePort', message: 'Node app port?', default: 9070},
547-
{type: 'input', name: 'guestAccess', message: 'Allow anonymous users to search data?', default: 'false'},
548-
{type: 'input', name: 'readOnlyAccess', message: 'Disallow proxying update requests?', default: 'false'},
549-
{type: 'input', name: 'appUsersOnly', message: 'Only allow access to users created for this app? Disallows admin users.', default: 'false'}
547+
{type: 'list', name: 'guestAccess', message: 'Allow anonymous users to search data?', choices: ['false', 'true'], default: 0},
548+
{type: 'list', name: 'readOnlyAccess', message: 'Disallow proxying update requests?', choices: ['false', 'true'], default: 0},
549+
{type: 'list', name: 'appUsersOnly', message: 'Only allow access to users created for this app? Note: disallows admin users.', choices: ['false', 'true'], default: 0}
550550
];
551551

552552
if (typeof appName === 'undefined') {

app/templates/node-server/proxy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ router.put('*', function(req, res) {
3737
res.status(401).send('Unauthorized');
3838
} else if (options.readOnlyAccess || (req.path === '/v1/documents' &&
3939
req.query.uri.match('/api/users/') &&
40-
req.query.uri.match(new RegExp('/api/users/[^(' + req.session.user.name + ')]+.json')))) {
40+
req.query.uri.match(new RegExp('/api/users/[^(' + req.session.user.username + ')]+.json')))) {
4141
// The user is trying to PUT to a profile document other than his/her own. Not allowed.
4242
res.status(403).send('Forbidden');
4343
} else {
@@ -83,8 +83,8 @@ router.delete('*', function(req, res) {
8383

8484
function getAuth(options, session) {
8585
var auth = null;
86-
if (session.user !== undefined && session.user.name !== undefined) {
87-
auth = session.user.name + ':' + session.user.password;
86+
if (session.user !== undefined && session.user.username !== undefined) {
87+
auth = session.user.username + ':' + session.user.password;
8888
}
8989
else {
9090
auth = options.defaultUser + ':' + options.defaultPass;

app/templates/node-server/routes.js

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,27 @@ router.get('/user/status', function(req, res) {
2020
res.send({
2121
authenticated: true,
2222
username: options.defaultUser,
23-
profile: { fullname: 'Guest' }
23+
profile: { fullname: 'Guest' },
24+
guestAccess: options.guestAccess,
25+
readOnlyAccess: options.readOnlyAccess,
26+
appUsersOnly: options.appUsersOnly
2427
});
2528
} else {
26-
res.send({authenticated: false});
29+
res.send({
30+
authenticated: false,
31+
guestAccess: options.guestAccess,
32+
readOnlyAccess: options.readOnlyAccess,
33+
appUsersOnly: options.appUsersOnly
34+
});
2735
}
2836
} else {
2937
delete headers['content-length'];
3038
var status = http.get({
3139
hostname: options.mlHost,
3240
port: options.mlHttpPort,
33-
path: '/v1/documents?uri=/api/users/' + req.session.user.name + '.json',
41+
path: '/v1/documents?uri=/api/users/' + req.session.user.username + '.json',
3442
headers: headers,
35-
auth: req.session.user.name + ':' + req.session.user.password
43+
auth: req.session.user.username + ':' + req.session.user.password
3644
}, function(response) {
3745
if (response.statusCode === 200) {
3846
response.on('data', function(chunk) {
@@ -42,17 +50,23 @@ router.get('/user/status', function(req, res) {
4250
}
4351
res.status(200).send({
4452
authenticated: true,
45-
username: req.session.user.name,
46-
profile: json.user || {}
53+
username: req.session.user.username,
54+
profile: json.user || {},
55+
guestAccess: options.guestAccess,
56+
readOnlyAccess: options.readOnlyAccess,
57+
appUsersOnly: options.appUsersOnly
4758
});
4859
req.session.user.profile = json.user || {};
4960
});
5061
} else if (response.statusCode === 404) {
5162
//no profile yet for user
5263
res.status(200).send({
5364
authenticated: true,
54-
username: req.session.user.name,
55-
profile: req.session.user.profile || {}
65+
username: req.session.user.username,
66+
profile: req.session.user.profile || {},
67+
guestAccess: options.guestAccess,
68+
readOnlyAccess: options.readOnlyAccess,
69+
appUsersOnly: options.appUsersOnly
5670
});
5771
} else {
5872
res.send({authenticated: false});
@@ -98,20 +112,23 @@ router.post('/user/login', function(req, res) {
98112
} else if (response.statusCode === 404) {
99113
// authentication successful, but no profile defined
100114
req.session.user = {
101-
name: username,
115+
username: username,
102116
password: password
103117
};
104118
res.status(200).send({
105119
authenticated: true,
106120
username: username,
107-
profile: {}
121+
profile: {},
122+
guestAccess: options.guestAccess,
123+
readOnlyAccess: options.readOnlyAccess,
124+
appUsersOnly: options.appUsersOnly
108125
});
109126
} else {
110127
console.log('code: ' + response.statusCode);
111128
if (response.statusCode === 200) {
112129
// authentication successful, remember the username
113130
req.session.user = {
114-
name: username,
131+
username: username,
115132
password: password
116133
};
117134
response.on('data', function(chunk) {
@@ -122,7 +139,10 @@ router.post('/user/login', function(req, res) {
122139
res.status(200).send({
123140
authenticated: true,
124141
username: username,
125-
profile: json.user || {}
142+
profile: json.user || {},
143+
guestAccess: options.guestAccess,
144+
readOnlyAccess: options.readOnlyAccess,
145+
appUsersOnly: options.appUsersOnly
126146
});
127147
req.session.user.profile = json.user || {};
128148
});

app/templates/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
"del": "^2.0.2",
1414
"glob": "^6.0.0",
1515
"gulp": "^3.8.0",
16-
"gulp-header": "1.8.2",
17-
"gulp-angular-templatecache": "^1.6.0",
16+
"gulp-angular-templatecache": "^1.9.1",
1817
"gulp-autoprefixer": "^2.2.0",
1918
"gulp-bump": "^1.0.0",
2019
"gulp-bytediff": "^1.0.0",

app/templates/ui/app/create/create.controller.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@
5353
// 'perm:sample-role': 'read',
5454
// 'perm:sample-role': 'update'
5555
}).then(function(response) {
56-
toast.success('Record created.');
56+
toast.success('Created');
5757
$state.go('root.view', { uri: response.replace(/(.*\?uri=)/, '') });
58+
}, function(response) {
59+
toast.danger(response.data);
5860
});
5961
}
6062

app/templates/ui/app/create/create.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="create" ng-if="ctrl.currentUser">
1+
<div class="create" ng-show="ctrl.currentUser && !ctrl.currentUser.readOnlyAccess">
22
<div class="row">
33
<div class="col-sm-2"></div>
44
<h2 class="col-sm-10">Create a Document</h2>
@@ -111,8 +111,8 @@ <h2 class="col-sm-10">Create a Document</h2>
111111
</div>
112112

113113
<div class="row">
114-
<a class="col-sm-offset-10 btn btn-default" ui-sref="root">Cancel</a>
115-
<button class="btn btn-primary" ng-click="ctrl.submit()">Submit</button>
114+
<a class="col-sm-offset-10 btn btn-default" ui-sref="root.landing">Cancel</a>
115+
<button class="btn btn-primary" ng-click="ctrl.submit()">Create</button>
116116
</div>
117117
</form>
118118
</div>

0 commit comments

Comments
 (0)