Skip to content
This repository was archived by the owner on Apr 20, 2024. It is now read-only.

Commit 07cd043

Browse files
authored
Merge pull request #46 from nodes-vapor/develop
Should reset pw is now working
2 parents e751370 + dd948cc commit 07cd043

File tree

11 files changed

+179
-69
lines changed

11 files changed

+179
-69
lines changed

Sources/AdminPanel/Controllers/BackendUsersController.swift

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public final class BackendUsersController {
3131
* - return: View
3232
*/
3333
public func index(request: Request) throws -> ResponseRepresentable {
34-
try Gate.allowOrFail(request, "super-admin")
34+
try Gate.allowOrFail(request, "admin")
3535

3636
let query = try BackendUser.query()
3737
if let search: String = request.query?["search"]?.string {
@@ -52,12 +52,12 @@ public final class BackendUsersController {
5252
* - return: View
5353
*/
5454
public func create(request: Request) throws -> ResponseRepresentable {
55-
try Gate.allowOrFail(request, "super-admin")
55+
try Gate.allowOrFail(request, "admin")
5656

5757
return try drop.view.make("BackendUsers/edit", [
58-
"roles": Configuration.shared?.roleOptions.makeNode() ?? [],
5958
"fieldset": BackendUserForm.getFieldset(request),
60-
"defaultRole": Configuration.shared?.defaultRole ?? "admin"
59+
"roles": Configuration.shared?.getRoleOptions(request.authedBackendUser().role).makeNode() ?? [:],
60+
"defaultRole": (Configuration.shared?.defaultRole ?? "user").makeNode()
6161
], for: request)
6262
}
6363

@@ -68,14 +68,14 @@ public final class BackendUsersController {
6868
* - return: View
6969
*/
7070
public func store(request: Request) throws -> ResponseRepresentable {
71-
try Gate.allowOrFail(request, "super-admin")
71+
try Gate.allowOrFail(request, "admin")
7272

7373
do {
7474
// Validate
7575
let backendUserForm = try BackendUserForm(validating: request.data)
7676

7777
// Store
78-
var backendUser = BackendUser(form: backendUserForm)
78+
var backendUser = try BackendUser(form: backendUserForm, request: request)
7979
try backendUser.save()
8080

8181
// Send welcome mail
@@ -99,14 +99,17 @@ public final class BackendUsersController {
9999
* - param: BackendUser
100100
* - return: View
101101
*/
102-
public func edit(request: Request, user: BackendUser) throws -> ResponseRepresentable {
103-
try Gate.allowOrFail(request, "super-admin")
102+
public func edit(request: Request, backendUser: BackendUser) throws -> ResponseRepresentable {
103+
if try backendUser.id != request.auth.user().id {
104+
try Gate.allowOrFail(request, "admin")
105+
try Gate.allowOrFail(request, backendUser.role)
106+
}
104107

105108
return try drop.view.make("BackendUsers/edit", [
106109
"fieldset": BackendUserForm.getFieldset(request),
107-
"backendUser": try user.makeNode(),
108-
"roles": Configuration.shared?.roleOptions.makeNode() ?? [],
109-
"defaultRole": Configuration.shared?.defaultRole ?? "admin"
110+
"backendUser": try backendUser.makeNode(),
111+
"roles": Configuration.shared?.getRoleOptions(request.authedBackendUser().role).makeNode() ?? [:],
112+
"defaultRole": (Configuration.shared?.defaultRole ?? "user").makeNode()
110113
], for: request)
111114
}
112115

@@ -118,21 +121,30 @@ public final class BackendUsersController {
118121
* - return: View
119122
*/
120123
public func update(request: Request) throws -> ResponseRepresentable {
121-
try Gate.allowOrFail(request, "super-admin")
122-
123124
guard let id = request.data["id"]?.int, var backendUser = try BackendUser.query().filter("id", id).first() else {
124125
throw Abort.notFound
125126
}
126127

128+
129+
if try backendUser.id != request.auth.user().id {
130+
try Gate.allowOrFail(request, "admin")
131+
try Gate.allowOrFail(request, backendUser.role)
132+
}
133+
127134
do {
128135
// Validate
129136
let backendUserForm = try BackendUserForm(validating: request.data)
130137

131138
// Store
132-
backendUser.fill(form: backendUserForm)
139+
try backendUser.fill(form: backendUserForm, request: request)
133140
try backendUser.save()
134141

135-
return Response(redirect: "/admin/backend_users").flash(.success, "User updated")
142+
if Gate.allow(request, "admin") {
143+
return Response(redirect: "/admin/backend_users").flash(.success, "User updated")
144+
} else {
145+
return Response(redirect: "/admin/backend_users/edit/" + String(id)).flash(.success, "User updated")
146+
}
147+
136148
}catch FormError.validationFailed(let fieldSet) {
137149
return Response(redirect: "/admin/backend_users/edit/" + String(id)).flash(.error, "Validation error").withFieldset(fieldSet)
138150
}catch {
@@ -147,11 +159,11 @@ public final class BackendUsersController {
147159
* - param: BackendUser
148160
* - return: View
149161
*/
150-
public func destroy(request: Request, user: BackendUser) throws -> ResponseRepresentable {
151-
try Gate.allowOrFail(request, "super-admin")
152-
162+
public func destroy(request: Request, backendUser: BackendUser) throws -> ResponseRepresentable {
163+
try Gate.allowOrFail(request, "admin")
164+
try Gate.allowOrFail(request, backendUser.role)
153165
do {
154-
try user.delete()
166+
try backendUser.delete()
155167
return Response(redirect: "/admin/backend_users").flash(.success, "Deleted user")
156168
} catch {
157169
return Response(redirect: "/admin/backend_users").flash(.error, "Failed to delete user")

Sources/AdminPanel/Models/BackendUsers/BackendUser.swift

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,41 @@ public final class BackendUser: Auth.User, Model {
4747
self.createdAt = Date()
4848
}
4949

50-
public init(form: BackendUserForm){
50+
public init(form: BackendUserForm, request: Request) throws {
5151
name = form.name
5252
email = form.email
53-
role = form.role
53+
54+
// Only super admins can update roles
55+
let rolesForUser = try Configuration.shared?.getRoleOptions(request.authedBackendUser().role) ?? [:]
56+
if rolesForUser[form.role] != nil {
57+
role = form.role
58+
} else {
59+
role = Configuration.shared?.defaultRole ?? "user"
60+
}
61+
5462
password = BCrypt.hash(password: form.password)
55-
shouldResetPassword = form.shouldResetPassword
63+
if let shouldResetPassword = form.shouldResetPassword {
64+
self.shouldResetPassword = shouldResetPassword
65+
}
5666

5767
self.updatedAt = Date()
5868
self.createdAt = Date()
5969
}
6070

61-
public func fill(form: BackendUserForm) {
71+
public func fill(form: BackendUserForm, request: Request) throws {
6272
name = form.name
6373
email = form.email
64-
role = form.role
74+
75+
// Only super admins can update roles
76+
let rolesForUser = try Configuration.shared?.getRoleOptions(request.authedBackendUser().role) ?? [:]
77+
if rolesForUser[form.role] != nil {
78+
role = form.role
79+
}
80+
81+
if let shouldResetPassword = form.shouldResetPassword {
82+
self.shouldResetPassword = shouldResetPassword
83+
}
84+
6585
updatedAt = Date()
6686

6787
if(!form.randomPassword) {

Sources/AdminPanel/Models/BackendUsers/BackendUserForm.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public struct BackendUserForm: Form {
88
let password: String
99
let sendMail: Bool
1010
var randomPassword = false
11-
let shouldResetPassword: Bool
11+
var shouldResetPassword: Bool? = nil
1212

1313
public static let fieldset = Fieldset([
1414
"name": StringField(
@@ -72,7 +72,7 @@ public struct BackendUserForm: Form {
7272
shouldResetPassword = true
7373
} else if validatedData["should_reset_password"] != nil {
7474
shouldResetPassword = true
75-
} else {
75+
} else if validatedData["password"]?.string != nil {
7676
shouldResetPassword = false
7777
}
7878
}

Sources/AdminPanel/Resources/Views/BackendUsers/edit.leaf

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@
3838
<div class="margin-vertical-sm">
3939
#form:textgroup("name", backendUser.name, fieldset)
4040
#form:emailgroup("email", backendUser.email, fieldset)
41-
#form:selectgroup("role", roles, fieldset, defaultRole)
41+
#if(backendUser) {
42+
#form:selectgroup("role", roles, fieldset, backendUser.role)
43+
} ##else() {
44+
#form:selectgroup("role", roles, fieldset, defaultRole)
45+
}
4246

43-
#if(#(backendUser)) {
47+
#if(backendUser) {
4448
} ##else() {
4549
#form:checkboxgroup("send_mail", "true", fieldset)
4650
}

Sources/AdminPanel/Resources/Views/BackendUsers/index.leaf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
</td>
5353
<td class="text-center">#(user.role)</td>
5454
<td class="text-center">
55+
56+
#allow(request, user.role) {
5557
<a href="/admin/backend_users/edit/#(user.id)" class="btn btn-sm btn-default" data-tooltip="true" title="Edit details">
5658
<span class="fa fa-pencil"></span>
5759
<span class="sr-only">Edit details</span>
@@ -60,6 +62,8 @@
6062
<span class="fa fa-times"></span>
6163
<span class="sr-only">Delete user</span>
6264
</a>
65+
}
66+
6367
<td>
6468
</tr>
6569
}

Sources/AdminPanel/Resources/Views/Emails/reset-password.leaf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
To reset your password, click the following link:<br>
1414
<a href="#(url)/admin/login/reset/#(token)">#(url)/admin/login/reset/#(token)</a>
1515
</p>
16+
17+
<p>
18+
If you can't use the click above, please copy paste the following into your browser:
19+
<br>
20+
#(url)/admin/login/reset/#(token)
21+
</p>
22+
1623
<p><em>This reset password request will expire in #(expire) minutes.</em></p>
24+
1725
</body>
1826
</html>

Sources/AdminPanel/Resources/Views/Layout/Partials/Navigation/navigation.leaf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@
1313
<li class="list-group-heading">
1414
Super admin
1515
</li>
16-
<li class="list-group-item #active(request, "/admin/backend_users", "/admin/backend_users/create", "/admin/backend_users/edit*")">
17-
<a href="/admin/backend_users">
18-
<i class="fa fa-street-view"></i>
19-
Backend users
20-
</a>
21-
</li>
2216
}
2317

2418
#allow(request, "admin") {
2519
<li class="list-group-heading">
2620
Admin
2721
</li>
2822

23+
<li class="list-group-item #active(request, "/admin/backend_users", "/admin/backend_users/create", "/admin/backend_users/edit*")">
24+
<a href="/admin/backend_users">
25+
<i class="fa fa-street-view"></i>
26+
Backend users
27+
</a>
28+
</li>
2929
}
3030
</ul>
Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11

2-
<div class="dropdown dropdown-user">
3-
<button class="btn btn-transparent dropdown-toggle user__info-button" data-toggle="dropdown">
4-
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)"/>
5-
<span class="user__info-name">
6-
#(request.storage.authedBackendUser.email)
7-
<span class="caret"></span>
8-
</span>
9-
</button>
10-
<div class="dropdown-menu dropdown-inverse animate-expand align-right">
11-
<div class="dropdown-content">
12-
<p class="dropdown-content__title">User</p>
13-
14-
<div class="user">
15-
<div class="user__profile">
16-
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)">
17-
</div>
18-
<div class="user__info">
19-
<span class="user__info-name">
20-
#(request.storage.authedBackendUser.name)
21-
</span>
22-
<span class="user__info-email">
23-
#(request.storage.authedBackendUser.email)
24-
</span>
25-
</div>
26-
</div>
27-
<div class="user-actions">
28-
<a href="/admin/backend_users/logout" class="btn btn-sm btn-transparent user__sign-out">
29-
<i class="fa fa-sign-out"></i>
30-
Sign out
31-
</a>
32-
<a href="/admin/users/edit/1" class="btn btn-sm btn-transparent user__settings" data-toggle="tooltip" data-placement="left" title="" data-original-title="Edit user">
33-
<i class="fa fa-pencil"></i>
34-
</a>
2+
<div class="dropdown dropdown-user">
3+
<button class="btn btn-transparent dropdown-toggle user__info-button" data-toggle="dropdown">
4+
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)"/>
5+
<span class="user__info-name">
6+
#(request.storage.authedBackendUser.email)
7+
<span class="caret"></span>
8+
</span>
9+
</button>
10+
<div class="dropdown-menu dropdown-inverse animate-expand align-right">
11+
<div class="dropdown-content">
12+
<p class="dropdown-content__title">User</p>
13+
14+
<div class="user">
15+
<div class="user__profile">
16+
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)">
17+
</div>
18+
<div class="user__info">
19+
<span class="user__info-name">
20+
#(request.storage.authedBackendUser.name)
21+
</span>
22+
<span class="user__info-email">
23+
#(request.storage.authedBackendUser.email)
24+
</span>
3525
</div>
3626
</div>
27+
<div class="user-actions">
28+
<a href="/admin/backend_users/logout" class="btn btn-sm btn-transparent user__sign-out">
29+
<i class="fa fa-sign-out"></i>
30+
Sign out
31+
</a>
32+
<a href="/admin/backend_users/edit/#(request.storage.authedBackendUser.id)" class="btn btn-sm btn-transparent user__settings" data-toggle="tooltip" data-placement="left" title="" data-original-title="Edit user">
33+
<i class="fa fa-pencil"></i>
34+
</a>
35+
</div>
3736
</div>
3837
</div>
38+
</div>

Sources/AdminPanel/Support/Configuration.swift

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ public struct Configuration {
5353
}
5454

5555
public var defaultRole: String {
56-
return "admin"
56+
for role in roles {
57+
if role.isDefault {
58+
return role.slug
59+
}
60+
}
61+
return "user"
5762
}
5863

5964
public init(drop: Droplet) throws {
@@ -125,4 +130,38 @@ public struct Configuration {
125130

126131
return roleArray
127132
}
133+
134+
public func getRoleOrFail(_ slug: String) throws -> Role {
135+
for role in roles {
136+
if role.slug == slug {
137+
return role
138+
}
139+
}
140+
141+
throw Abort.custom(status: .internalServerError, message: "The role \(slug) was not found")
142+
}
143+
144+
public func getRoles(_ slug: String) -> [Role] {
145+
var roles: [Role] = []
146+
147+
for role in self.roles {
148+
// Add roles which is on level or below the slug input param
149+
if role.slug == slug || roles.count > 0 {
150+
roles.append(role)
151+
}
152+
}
153+
154+
155+
return roles
156+
}
157+
158+
public func getRoleOptions(_ slug: String) -> [String : String] {
159+
var roles: [String : String] = [:]
160+
161+
for role in getRoles(slug) {
162+
roles[role.slug] = role.title
163+
}
164+
165+
return roles
166+
}
128167
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import VaporForms
2+
import HTTP
3+
import Vapor
4+
5+
extension Request {
6+
public func authedBackendUser() throws -> BackendUser {
7+
8+
guard let backendUser: BackendUser = try auth.user() as? BackendUser else {
9+
throw Abort.custom(status: .internalServerError, message: "The authed user is not a BackendUser")
10+
}
11+
12+
return backendUser
13+
}
14+
}

0 commit comments

Comments
 (0)