vines-services 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +5 -5
- data/Rakefile +13 -11
- data/bin/vines-services +0 -1
- data/lib/vines/services/command/init.rb +156 -139
- data/lib/vines/services/controller/messages_controller.rb +8 -3
- data/lib/vines/services/controller/users_controller.rb +11 -11
- data/lib/vines/services/indexer.rb +1 -1
- data/lib/vines/services/priority_queue.rb +12 -12
- data/lib/vines/services/roster.rb +85 -46
- data/lib/vines/services/storage/couchdb/service.rb +1 -1
- data/lib/vines/services/storage/couchdb/system.rb +1 -1
- data/lib/vines/services/storage/couchdb/upload.rb +1 -1
- data/lib/vines/services/storage/couchdb/user.rb +13 -3
- data/lib/vines/services/storage/couchdb.rb +8 -12
- data/lib/vines/services/version.rb +1 -1
- data/test/priority_queue_test.rb +1 -1
- data/web/coffeescripts/api.coffee +6 -0
- data/web/coffeescripts/files.coffee +65 -39
- data/web/coffeescripts/services.coffee +5 -2
- data/web/coffeescripts/setup.coffee +35 -12
- data/web/coffeescripts/systems.coffee +115 -228
- data/web/javascripts/api.js +69 -0
- data/web/javascripts/app.js +2 -0
- data/web/javascripts/commands.js +28 -0
- data/web/javascripts/files.js +424 -0
- data/web/javascripts/init.js +27 -0
- data/web/javascripts/services.js +404 -0
- data/web/javascripts/setup.js +485 -0
- data/web/javascripts/systems.js +342 -0
- data/web/stylesheets/app.css +714 -0
- data/web/stylesheets/services.css +4 -14
- data/web/stylesheets/setup.css +1 -2
- data/web/stylesheets/systems.css +124 -108
- metadata +95 -92
@@ -1,70 +1,109 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
|
2
3
|
module Vines
|
3
4
|
class Storage
|
4
5
|
class CouchDB < Storage
|
6
|
+
alias :_services_find_user :find_user
|
7
|
+
|
8
|
+
# Override the user's roster with an auto-populated roster containing
|
9
|
+
# the services and systems to which the user has permission to access.
|
10
|
+
def find_user(jid)
|
11
|
+
user = _services_find_user(jid)
|
12
|
+
return unless user
|
13
|
+
user.roster = []
|
14
|
+
|
15
|
+
systems, users = find_users.partition {|u| u['system'] }
|
16
|
+
systems.map! {|u| u['_id'].sub('user:', '') }
|
17
|
+
return user if systems.include?(user.jid.to_s)
|
18
|
+
services = find_services(user.jid)
|
19
|
+
|
20
|
+
users.each do |row|
|
21
|
+
id = row['_id'].sub('user:', '')
|
22
|
+
user.roster << Contact.new(
|
23
|
+
:jid => id,
|
24
|
+
:name => row['name'],
|
25
|
+
:subscription => 'both',
|
26
|
+
:groups => ['People']) unless id == jid.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
services.each do |row|
|
30
|
+
user.roster << Contact.new(
|
31
|
+
:jid => row['jid'],
|
32
|
+
:name => row['name'],
|
33
|
+
:subscription => 'to',
|
34
|
+
:groups => ['Services'])
|
35
|
+
end
|
36
|
+
|
37
|
+
find_systems(services).each do |name, groups|
|
38
|
+
id = JID.new(name.dup, user.jid.domain).to_s
|
39
|
+
user.roster << Contact.new(
|
40
|
+
:jid => id,
|
41
|
+
:name => name,
|
42
|
+
:subscription => 'to',
|
43
|
+
:groups => ['Systems', *groups]) if systems.include?(id)
|
44
|
+
end
|
5
45
|
|
6
|
-
|
46
|
+
user.roster << Contact.new(
|
47
|
+
:jid => "vines.#{user.jid.domain}",
|
48
|
+
:name => 'Vines',
|
49
|
+
:subscription => 'to')
|
50
|
+
user
|
51
|
+
end
|
7
52
|
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
http = EM::HttpRequest.new(
|
12
|
-
http.errback { yield }
|
53
|
+
# Return the User documents for all users and systems.
|
54
|
+
def find_users
|
55
|
+
url = "%s/_design/User/_view/all?reduce=false&include_docs=true" % @url
|
56
|
+
http = EM::HttpRequest.new(url).get
|
57
|
+
http.errback { yield [] }
|
13
58
|
http.callback do
|
14
59
|
doc = if http.response_header.status == 200
|
15
|
-
JSON.parse(http.response) rescue
|
60
|
+
rows = JSON.parse(http.response)['rows'] rescue []
|
61
|
+
rows.map {|row| row['doc'] }
|
16
62
|
end
|
17
|
-
yield doc
|
63
|
+
yield doc || []
|
18
64
|
end
|
19
65
|
end
|
66
|
+
fiber :find_users
|
20
67
|
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if doc['roster'] != ""
|
32
|
-
(doc['roster'] || {}).each_pair do |jid, props|
|
33
|
-
user.roster << Contact.new(
|
34
|
-
:jid => jid,
|
35
|
-
:name => props['name'],
|
36
|
-
:subscription => props['subscription'],
|
37
|
-
:ask => props['ask'],
|
38
|
-
:groups => props['groups'] || [])
|
39
|
-
end
|
40
|
-
end
|
41
|
-
add_user_roster_services(user)
|
42
|
-
end
|
68
|
+
# Return the Service documents to which this JID has permission to
|
69
|
+
# access.
|
70
|
+
def find_services(jid)
|
71
|
+
url = "%s/_design/Service/_view/by_user?reduce=false&key=%s" % [@url, escape(jid.to_s).to_json]
|
72
|
+
http = EM::HttpRequest.new(url).get
|
73
|
+
http.errback { yield [] }
|
74
|
+
http.callback do
|
75
|
+
doc = if http.response_header.status == 200
|
76
|
+
rows = JSON.parse(http.response)['rows'] rescue []
|
77
|
+
rows.map {|row| row['value'] }
|
43
78
|
end
|
44
|
-
yield
|
79
|
+
yield doc || []
|
45
80
|
end
|
46
81
|
end
|
47
|
-
fiber :
|
82
|
+
fiber :find_services
|
48
83
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
84
|
+
# Find the systems that belong to these services. Return a Hash of
|
85
|
+
# system name to list of service names to which it belongs.
|
86
|
+
def find_systems(services)
|
87
|
+
keys = services.map {|row| [0, row['_id']] }
|
88
|
+
url = "%s/_design/System/_view/memberships?reduce=false" % @url
|
89
|
+
http = EM::HttpRequest.new(url).post(
|
90
|
+
head: {'Content-Type' => 'application/json'},
|
91
|
+
body: {keys: keys}.to_json)
|
92
|
+
http.errback { yield [] }
|
93
|
+
http.callback do
|
94
|
+
doc = if http.response_header.status == 200
|
95
|
+
rows = JSON.parse(http.response)['rows'] rescue []
|
96
|
+
Hash.new {|h, k| h[k] = [] }.tap do |systems|
|
97
|
+
rows.each do |row|
|
98
|
+
service = services.find {|s| s['_id'] == row['key'][1] }
|
99
|
+
systems[row['value']['name']] << service['name']
|
63
100
|
end
|
64
101
|
end
|
65
102
|
end
|
103
|
+
yield doc || []
|
66
104
|
end
|
67
105
|
end
|
106
|
+
fiber :find_systems
|
68
107
|
end
|
69
108
|
end
|
70
109
|
end
|
@@ -6,7 +6,7 @@ module Vines
|
|
6
6
|
class Service < CouchRest::Model::Base
|
7
7
|
extend Storage::CouchDB::ClassMethods
|
8
8
|
|
9
|
-
KEYS = %w[_id name code accounts users jid created_at
|
9
|
+
KEYS = %w[_id name code accounts users jid created_at updated_at].freeze
|
10
10
|
VIEW_ID = "_design/System".freeze
|
11
11
|
VIEW_NAME = "System/memberships".freeze
|
12
12
|
|
@@ -6,7 +6,7 @@ module Vines
|
|
6
6
|
class System < CouchRest::Model::Base
|
7
7
|
extend Storage::CouchDB::ClassMethods
|
8
8
|
|
9
|
-
KEYS = %w[_id ohai created_at
|
9
|
+
KEYS = %w[_id ohai created_at updated_at].freeze
|
10
10
|
VIEW_NAME = "System/memberships".freeze
|
11
11
|
|
12
12
|
attr_writer :services
|
@@ -6,7 +6,7 @@ module Vines
|
|
6
6
|
class Upload < CouchRest::Model::Base
|
7
7
|
extend Storage::CouchDB::ClassMethods
|
8
8
|
|
9
|
-
KEYS = %w[_id name size labels created_at
|
9
|
+
KEYS = %w[_id name size labels created_at updated_at].freeze
|
10
10
|
|
11
11
|
property :name, String
|
12
12
|
property :size, Integer
|
@@ -6,7 +6,7 @@ module Vines
|
|
6
6
|
class User < CouchRest::Model::Base
|
7
7
|
extend Storage::CouchDB::ClassMethods
|
8
8
|
|
9
|
-
KEYS = %w[_id name permissions system created_at
|
9
|
+
KEYS = %w[_id name permissions system created_at updated_at].freeze
|
10
10
|
|
11
11
|
before_save :enforce_constraints
|
12
12
|
after_destroy :remove_references
|
@@ -51,6 +51,16 @@ module Vines
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# Grant this user all possible permissions.
|
55
|
+
def admin!
|
56
|
+
write_attribute('permissions', {
|
57
|
+
'systems' => true,
|
58
|
+
'services' => true,
|
59
|
+
'files' => true,
|
60
|
+
'users' => true
|
61
|
+
})
|
62
|
+
end
|
63
|
+
|
54
64
|
def permissions=(perms)
|
55
65
|
perms ||= {}
|
56
66
|
self.manage_systems = perms['systems']
|
@@ -59,7 +69,7 @@ module Vines
|
|
59
69
|
self.manage_users = perms['users']
|
60
70
|
end
|
61
71
|
|
62
|
-
def
|
72
|
+
def plain_password=(desired)
|
63
73
|
desired = (desired || '').strip
|
64
74
|
raise 'password too short' if desired.size < (system ? 128 : 8)
|
65
75
|
write_attribute('password', BCrypt::Password.create(desired))
|
@@ -68,7 +78,7 @@ module Vines
|
|
68
78
|
def change_password(previous, desired)
|
69
79
|
hash = BCrypt::Password.new(password) rescue nil
|
70
80
|
raise 'password failure' unless hash && hash == previous
|
71
|
-
self.
|
81
|
+
self.plain_password = desired
|
72
82
|
end
|
73
83
|
|
74
84
|
def jid
|
@@ -100,20 +100,13 @@ module Vines
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def create_views
|
103
|
-
# FIXME Use views in CouchRest::Model classes to populate db
|
104
|
-
designs = {}
|
105
|
-
|
106
103
|
EM.run do
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
doc ||= {"_id" => "_design/#{name}"}
|
111
|
-
doc['language'] = 'javascript'
|
112
|
-
doc['views'] = views
|
113
|
-
save(doc) { EM.stop }
|
114
|
-
end
|
104
|
+
Fiber.new do
|
105
|
+
CouchRest::Model::Base.subclasses.each do |klass|
|
106
|
+
klass.save_design_doc! if klass.respond_to?(:save_design_doc!)
|
115
107
|
end
|
116
|
-
|
108
|
+
EM.stop
|
109
|
+
end.resume
|
117
110
|
end
|
118
111
|
end
|
119
112
|
|
@@ -146,6 +139,9 @@ module Vines
|
|
146
139
|
*url, _ = @url.split('/')
|
147
140
|
server = CouchRest::Server.new(url.join('/'))
|
148
141
|
CouchRest::Model::Base.database = server.database(database)
|
142
|
+
CouchRest::Model::Base.configure do |config|
|
143
|
+
config.auto_update_design_doc = false
|
144
|
+
end
|
149
145
|
end
|
150
146
|
|
151
147
|
def escape(jid)
|
data/test/priority_queue_test.rb
CHANGED
@@ -9,8 +9,7 @@ class FilesPage
|
|
9
9
|
jid: @api.jid
|
10
10
|
size: this.size
|
11
11
|
complete: (file) =>
|
12
|
-
this.
|
13
|
-
this.findFiles name: file.name
|
12
|
+
this.findFile file.name
|
14
13
|
|
15
14
|
findLabels: ->
|
16
15
|
$('#labels').empty()
|
@@ -20,7 +19,7 @@ class FilesPage
|
|
20
19
|
labelNodeList: (label)->
|
21
20
|
text = if label.size == 1 then 'file' else 'files'
|
22
21
|
node = $("""
|
23
|
-
<li data-name=""
|
22
|
+
<li data-name="">
|
24
23
|
<span class="text"></span>
|
25
24
|
<span class="count">#{label.size} #{text}</span>
|
26
25
|
</li>
|
@@ -28,7 +27,6 @@ class FilesPage
|
|
28
27
|
$('.text', node).text label.name
|
29
28
|
node.attr 'data-name', label.name
|
30
29
|
node.click (event) => this.selectLabel(event)
|
31
|
-
node.fadeIn(100)
|
32
30
|
|
33
31
|
selectLabel: (event) ->
|
34
32
|
name = $(event.currentTarget).attr 'data-name'
|
@@ -41,19 +39,35 @@ class FilesPage
|
|
41
39
|
@api.get FILES, criteria, (result) =>
|
42
40
|
this.fileNode row for row in result.rows
|
43
41
|
|
44
|
-
|
42
|
+
findFile: (name) ->
|
43
|
+
@api.get FILES, name: name, (result) =>
|
44
|
+
this.fileNode result
|
45
|
+
|
46
|
+
updateFileNode: (file) ->
|
47
|
+
node = $ "#files li[data-id='#{file.id}']"
|
45
48
|
size = this.size file.size
|
46
|
-
if !file.created_at
|
47
|
-
file.created_at = Date()
|
48
49
|
time = this.date file.created_at
|
50
|
+
node.data 'file', file
|
51
|
+
$('h2', node).text file.name
|
52
|
+
$('.size', node).text size
|
53
|
+
$('.time', node).text time
|
54
|
+
node.attr 'data-name', file.name
|
55
|
+
node.attr 'data-size', size
|
56
|
+
node.attr 'data-created', time
|
57
|
+
|
58
|
+
fileNode: (file) ->
|
59
|
+
if $("#files li[data-id='#{file.id}']").length > 0
|
60
|
+
this.updateFileNode file
|
61
|
+
return
|
62
|
+
|
49
63
|
node = $("""
|
50
|
-
<li data-id="#{file.id}"
|
64
|
+
<li data-id="#{file.id}">
|
51
65
|
<div class="file-icon">
|
52
|
-
<span class="size"
|
66
|
+
<span class="size"></span>
|
53
67
|
</div>
|
54
68
|
<h2></h2>
|
55
69
|
<footer>
|
56
|
-
<span class="time"
|
70
|
+
<span class="time"></span>
|
57
71
|
<ul class="labels"></ul>
|
58
72
|
<form class="add-label">
|
59
73
|
<div class="add-label-button"></div>
|
@@ -68,10 +82,6 @@ class FilesPage
|
|
68
82
|
</li>
|
69
83
|
""").appendTo '#files'
|
70
84
|
|
71
|
-
node.data 'file', file
|
72
|
-
$('h2', node).text file.name
|
73
|
-
node.attr 'data-name', file.name
|
74
|
-
|
75
85
|
new Button $('.file-icon', node).get(0), ICONS.page2,
|
76
86
|
scale: 1.0
|
77
87
|
translation: '-2 0'
|
@@ -87,7 +97,8 @@ class FilesPage
|
|
87
97
|
$('.add-label-button', node).click ->
|
88
98
|
$('form.add-label input[type="text"]', node).show()
|
89
99
|
|
90
|
-
this.
|
100
|
+
this.updateFileNode file
|
101
|
+
this.labelNode(node, label) for label in file.labels
|
91
102
|
|
92
103
|
labelNode: (node, label) ->
|
93
104
|
labels = $('.labels', node)
|
@@ -115,8 +126,9 @@ class FilesPage
|
|
115
126
|
file = node.data 'file'
|
116
127
|
file.labels.push label for label in labels
|
117
128
|
@api.save FILES, file, (result) ->
|
118
|
-
|
119
|
-
|
129
|
+
for label in labels
|
130
|
+
this.labelNode node, label
|
131
|
+
this.updateLabelCount label, 1
|
120
132
|
false
|
121
133
|
|
122
134
|
removeLabel: (node, item) ->
|
@@ -125,10 +137,21 @@ class FilesPage
|
|
125
137
|
file.labels = (label for label in file.labels when label != remove)
|
126
138
|
@api.save FILES, file, (result) ->
|
127
139
|
item.fadeOut 200, -> item.remove()
|
128
|
-
this.
|
140
|
+
this.updateLabelCount remove, -1
|
141
|
+
|
142
|
+
updateLabelCount: (name, inc) ->
|
143
|
+
el = $ "#labels li[data-name='#{name}'] .count"
|
144
|
+
if el.length > 0
|
145
|
+
count = parseInt(el.text().split(' ')[0]) + inc
|
146
|
+
text = if count == 1 then 'file' else 'files'
|
147
|
+
el.text "#{count} #{text}"
|
148
|
+
else
|
149
|
+
this.labelNodeList(name: name, size: 1)
|
129
150
|
|
130
151
|
deleteFile: (node) ->
|
131
152
|
@api.remove FILES, node.attr('data-id'), (result) =>
|
153
|
+
for label in node.data('file').labels
|
154
|
+
this.updateLabelCount label, -1
|
132
155
|
node.fadeOut 200, -> node.remove()
|
133
156
|
false
|
134
157
|
|
@@ -188,31 +211,35 @@ class FilesPage
|
|
188
211
|
</div>
|
189
212
|
""").appendTo '#container'
|
190
213
|
|
191
|
-
|
192
|
-
|
193
|
-
|
214
|
+
if @api.user.permissions.files
|
215
|
+
$('#file-chooser').change (event) =>
|
216
|
+
@uploads.queue event.target.files
|
217
|
+
$('#file-chooser').val ''
|
194
218
|
|
195
|
-
|
196
|
-
|
197
|
-
|
219
|
+
$('#file-form').submit ->
|
220
|
+
$('#file-chooser').click()
|
221
|
+
false
|
198
222
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
223
|
+
$('#upload-dnd').bind 'dragenter', (event) ->
|
224
|
+
event.stopPropagation()
|
225
|
+
event.preventDefault()
|
226
|
+
$('#upload-dnd').css 'color', '#444'
|
203
227
|
|
204
|
-
|
205
|
-
|
228
|
+
$('#upload-dnd').bind 'dragleave', (event) ->
|
229
|
+
$('#upload-dnd').css 'color', '#ababab'
|
206
230
|
|
207
|
-
|
208
|
-
|
209
|
-
|
231
|
+
$('#upload-dnd').bind 'dragover', (event) ->
|
232
|
+
event.stopPropagation()
|
233
|
+
event.preventDefault()
|
210
234
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
235
|
+
$('#upload-dnd').bind 'drop', (event) =>
|
236
|
+
event.stopPropagation()
|
237
|
+
event.preventDefault()
|
238
|
+
$('#upload-dnd').css 'color', '#ababab'
|
239
|
+
@uploads.queue event.originalEvent.dataTransfer.files
|
240
|
+
else
|
241
|
+
$('#upload-dnd').text "Your account cannot upload files."
|
242
|
+
$('#file-form').remove()
|
216
243
|
|
217
244
|
this.findLabels()
|
218
245
|
this.findFiles()
|
@@ -278,7 +305,6 @@ class FilesPage
|
|
278
305
|
upload.start()
|
279
306
|
else
|
280
307
|
@sending = null
|
281
|
-
this.fileNode(upload.file)
|
282
308
|
|
283
309
|
find: (file) ->
|
284
310
|
(up for up in @uploads when up.file.name == file.name).shift()
|
@@ -173,9 +173,10 @@ class ServicesPage
|
|
173
173
|
criteria you define. Send a command to the service and it runs
|
174
174
|
on every system in the group.
|
175
175
|
</p>
|
176
|
-
<input type="submit" id="blank-slate-add" value="
|
176
|
+
<input type="submit" id="blank-slate-add" value="Add Service"/>
|
177
177
|
</form>
|
178
178
|
""").appendTo '#beta'
|
179
|
+
$('#blank-slate-add').remove() unless @api.user.permissions.services
|
179
180
|
$('#blank-slate').submit =>
|
180
181
|
this.drawEditor()
|
181
182
|
false
|
@@ -218,6 +219,8 @@ class ServicesPage
|
|
218
219
|
new Button '#add-service', ICONS.plus
|
219
220
|
new Button '#remove-service', ICONS.minus
|
220
221
|
|
222
|
+
$('#alpha-controls div').remove() unless @api.user.permissions.services
|
223
|
+
|
221
224
|
this.drawBlankSlate()
|
222
225
|
|
223
226
|
$('#add-service').click => this.drawEditor()
|
@@ -272,7 +275,7 @@ class ServicesPage
|
|
272
275
|
<input id="name" type="text"/>
|
273
276
|
<p id="name-error" class="error"></p>
|
274
277
|
<label for="syntax">Criteria</label>
|
275
|
-
<textarea id="syntax" placeholder="fqdn
|
278
|
+
<textarea id="syntax" placeholder="fqdn starts with 'www.' and platform is 'mac_os_x'"></textarea>
|
276
279
|
<p id="syntax-status"></p>
|
277
280
|
</fieldset>
|
278
281
|
</section>
|
@@ -31,7 +31,7 @@ class SetupPage
|
|
31
31
|
""").appendTo '#services'
|
32
32
|
$('label', node).text service.name
|
33
33
|
$('#services input[type="checkbox"]').val @selected.services if @selected
|
34
|
-
if @selected && !@
|
34
|
+
if @selected && !@api.user.permissions.services
|
35
35
|
$('#services input[type="checkbox"]').prop 'disabled', true
|
36
36
|
|
37
37
|
findUsers: ->
|
@@ -48,17 +48,15 @@ class SetupPage
|
|
48
48
|
|
49
49
|
userNode: (user) ->
|
50
50
|
node = $("""
|
51
|
-
<li data-name="" data-jid="" id="#{user.jid}">
|
51
|
+
<li data-name="" data-jid="#{user.jid}" id="#{user.jid}">
|
52
52
|
<span class="text"></span>
|
53
|
-
<span class="jid"
|
53
|
+
<span class="jid">#{user.jid}</span>
|
54
54
|
</li>
|
55
55
|
""").appendTo '#users'
|
56
56
|
|
57
57
|
name = this.userName(user)
|
58
58
|
$('.text', node).text name
|
59
|
-
$('.jid', node).text user.jid
|
60
59
|
node.attr 'data-name', name
|
61
|
-
node.attr 'data-jid', user.jid
|
62
60
|
node.click (event) => this.selectUser event.currentTarget
|
63
61
|
node
|
64
62
|
|
@@ -105,10 +103,18 @@ class SetupPage
|
|
105
103
|
$('#beta-header').text 'Users'
|
106
104
|
this.drawUsers()
|
107
105
|
this.drawUserBlankSlate()
|
106
|
+
if @api.user.permissions.users
|
107
|
+
$('#beta-controls div').show()
|
108
|
+
else
|
109
|
+
$('#beta-controls div').hide()
|
108
110
|
when 'systems-nav'
|
109
111
|
$('#beta-header').text 'Systems'
|
110
112
|
this.drawUsers()
|
111
113
|
this.drawSystemBlankSlate()
|
114
|
+
if @api.user.permissions.systems
|
115
|
+
$('#beta-controls div').show()
|
116
|
+
else
|
117
|
+
$('#beta-controls div').hide()
|
112
118
|
|
113
119
|
toggleForm: (form, fn) ->
|
114
120
|
form = $(form)
|
@@ -136,6 +142,12 @@ class SetupPage
|
|
136
142
|
$('#password-error').text 'Password must be at least 8 characters.'
|
137
143
|
valid = false
|
138
144
|
|
145
|
+
# admin updating a user's password
|
146
|
+
if @session.bareJid() != @selected.jid
|
147
|
+
if password1 != password2
|
148
|
+
$('#password-error').text 'Passwords must match.'
|
149
|
+
valid = false
|
150
|
+
|
139
151
|
else # new user
|
140
152
|
if node == ''
|
141
153
|
$('#user-name-error').text 'User name is required.'
|
@@ -160,7 +172,7 @@ class SetupPage
|
|
160
172
|
valid
|
161
173
|
|
162
174
|
saveUser: ->
|
163
|
-
return unless this.validateUser()
|
175
|
+
return false unless this.validateUser()
|
164
176
|
user =
|
165
177
|
jid: $('#jid').val()
|
166
178
|
username: $('#user-name').val()
|
@@ -201,7 +213,7 @@ class SetupPage
|
|
201
213
|
valid
|
202
214
|
|
203
215
|
saveSystem: ->
|
204
|
-
return unless this.validateSystem()
|
216
|
+
return false unless this.validateSystem()
|
205
217
|
user =
|
206
218
|
jid: $('#jid').val()
|
207
219
|
username: $('#user-name').val()
|
@@ -229,14 +241,18 @@ class SetupPage
|
|
229
241
|
|
230
242
|
drawUserBlankSlate: ->
|
231
243
|
$('#charlie').empty()
|
244
|
+
msg = if @api.user.permissions.users
|
245
|
+
'Select a user account to update or add a new user.'
|
246
|
+
else
|
247
|
+
'Select a user account to update.'
|
248
|
+
|
232
249
|
$("""
|
233
250
|
<form id="blank-slate">
|
234
|
-
<p>
|
235
|
-
Select a user account to edit or add a new user.
|
236
|
-
</p>
|
251
|
+
<p>#{msg}</p>
|
237
252
|
<input type="submit" id="blank-slate-add" value="Add User"/>
|
238
253
|
</form>
|
239
254
|
""").appendTo '#charlie'
|
255
|
+
$('#blank-slate-add').remove() unless @api.user.permissions.users
|
240
256
|
$('#blank-slate').submit =>
|
241
257
|
this.drawUserEditor()
|
242
258
|
false
|
@@ -252,6 +268,7 @@ class SetupPage
|
|
252
268
|
<input type="submit" id="blank-slate-add" value="Add System"/>
|
253
269
|
</form>
|
254
270
|
""").appendTo '#charlie'
|
271
|
+
$('#blank-slate-add').remove() unless @api.user.permissions.systems
|
255
272
|
$('#blank-slate').submit =>
|
256
273
|
this.drawSystemEditor()
|
257
274
|
false
|
@@ -295,6 +312,7 @@ class SetupPage
|
|
295
312
|
</div>
|
296
313
|
<div id="charlie" class="primary column x-fill y-fill"></div>
|
297
314
|
""").appendTo '#container'
|
315
|
+
|
298
316
|
this.drawUserBlankSlate()
|
299
317
|
|
300
318
|
$('#setup li').click (event) => this.selectTask event
|
@@ -308,6 +326,9 @@ class SetupPage
|
|
308
326
|
new Button '#add-user', ICONS.plus
|
309
327
|
new Button '#remove-user', ICONS.minus
|
310
328
|
|
329
|
+
$('#beta-controls div').hide() unless @api.user.permissions.users
|
330
|
+
$('#systems-nav').hide() unless @api.user.permissions.systems
|
331
|
+
|
311
332
|
$('#add-user').click =>
|
312
333
|
if $('#users-nav').hasClass 'selected'
|
313
334
|
this.drawUserEditor()
|
@@ -326,7 +347,7 @@ class SetupPage
|
|
326
347
|
list: '#users'
|
327
348
|
icon: '#search-users-icon'
|
328
349
|
form: '#search-users-form'
|
329
|
-
attrs: ['data-jid']
|
350
|
+
attrs: ['data-jid', 'data-name']
|
330
351
|
open: fn
|
331
352
|
close: fn
|
332
353
|
|
@@ -402,7 +423,9 @@ class SetupPage
|
|
402
423
|
""").prependTo '#jid-fields'
|
403
424
|
|
404
425
|
$('#name').focus()
|
405
|
-
|
426
|
+
if @session.bareJid() != user.jid
|
427
|
+
$('#password1-label').text 'Password'
|
428
|
+
$('#password2-label').text 'Password Again'
|
406
429
|
$('#jid').val user.jid
|
407
430
|
$('#name').val user.name
|
408
431
|
$('#user-name').val user.jid.split('@')[0]
|