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

Commit

Permalink
Merge pull request #46 from nodes-vapor/develop
Browse files Browse the repository at this point in the history
Should reset pw is now working
  • Loading branch information
Casperhr authored Mar 12, 2017
2 parents e751370 + dd948cc commit 07cd043
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 69 deletions.
50 changes: 31 additions & 19 deletions Sources/AdminPanel/Controllers/BackendUsersController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public final class BackendUsersController {
* - return: View
*/
public func index(request: Request) throws -> ResponseRepresentable {
try Gate.allowOrFail(request, "super-admin")
try Gate.allowOrFail(request, "admin")

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

return try drop.view.make("BackendUsers/edit", [
"roles": Configuration.shared?.roleOptions.makeNode() ?? [],
"fieldset": BackendUserForm.getFieldset(request),
"defaultRole": Configuration.shared?.defaultRole ?? "admin"
"roles": Configuration.shared?.getRoleOptions(request.authedBackendUser().role).makeNode() ?? [:],
"defaultRole": (Configuration.shared?.defaultRole ?? "user").makeNode()
], for: request)
}

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

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

// Store
var backendUser = BackendUser(form: backendUserForm)
var backendUser = try BackendUser(form: backendUserForm, request: request)
try backendUser.save()

// Send welcome mail
Expand All @@ -99,14 +99,17 @@ public final class BackendUsersController {
* - param: BackendUser
* - return: View
*/
public func edit(request: Request, user: BackendUser) throws -> ResponseRepresentable {
try Gate.allowOrFail(request, "super-admin")
public func edit(request: Request, backendUser: BackendUser) throws -> ResponseRepresentable {
if try backendUser.id != request.auth.user().id {
try Gate.allowOrFail(request, "admin")
try Gate.allowOrFail(request, backendUser.role)
}

return try drop.view.make("BackendUsers/edit", [
"fieldset": BackendUserForm.getFieldset(request),
"backendUser": try user.makeNode(),
"roles": Configuration.shared?.roleOptions.makeNode() ?? [],
"defaultRole": Configuration.shared?.defaultRole ?? "admin"
"backendUser": try backendUser.makeNode(),
"roles": Configuration.shared?.getRoleOptions(request.authedBackendUser().role).makeNode() ?? [:],
"defaultRole": (Configuration.shared?.defaultRole ?? "user").makeNode()
], for: request)
}

Expand All @@ -118,21 +121,30 @@ public final class BackendUsersController {
* - return: View
*/
public func update(request: Request) throws -> ResponseRepresentable {
try Gate.allowOrFail(request, "super-admin")

guard let id = request.data["id"]?.int, var backendUser = try BackendUser.query().filter("id", id).first() else {
throw Abort.notFound
}


if try backendUser.id != request.auth.user().id {
try Gate.allowOrFail(request, "admin")
try Gate.allowOrFail(request, backendUser.role)
}

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

// Store
backendUser.fill(form: backendUserForm)
try backendUser.fill(form: backendUserForm, request: request)
try backendUser.save()

return Response(redirect: "/admin/backend_users").flash(.success, "User updated")
if Gate.allow(request, "admin") {
return Response(redirect: "/admin/backend_users").flash(.success, "User updated")
} else {
return Response(redirect: "/admin/backend_users/edit/" + String(id)).flash(.success, "User updated")
}

}catch FormError.validationFailed(let fieldSet) {
return Response(redirect: "/admin/backend_users/edit/" + String(id)).flash(.error, "Validation error").withFieldset(fieldSet)
}catch {
Expand All @@ -147,11 +159,11 @@ public final class BackendUsersController {
* - param: BackendUser
* - return: View
*/
public func destroy(request: Request, user: BackendUser) throws -> ResponseRepresentable {
try Gate.allowOrFail(request, "super-admin")

public func destroy(request: Request, backendUser: BackendUser) throws -> ResponseRepresentable {
try Gate.allowOrFail(request, "admin")
try Gate.allowOrFail(request, backendUser.role)
do {
try user.delete()
try backendUser.delete()
return Response(redirect: "/admin/backend_users").flash(.success, "Deleted user")
} catch {
return Response(redirect: "/admin/backend_users").flash(.error, "Failed to delete user")
Expand Down
30 changes: 25 additions & 5 deletions Sources/AdminPanel/Models/BackendUsers/BackendUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,41 @@ public final class BackendUser: Auth.User, Model {
self.createdAt = Date()
}

public init(form: BackendUserForm){
public init(form: BackendUserForm, request: Request) throws {
name = form.name
email = form.email
role = form.role

// Only super admins can update roles
let rolesForUser = try Configuration.shared?.getRoleOptions(request.authedBackendUser().role) ?? [:]
if rolesForUser[form.role] != nil {
role = form.role
} else {
role = Configuration.shared?.defaultRole ?? "user"
}

password = BCrypt.hash(password: form.password)
shouldResetPassword = form.shouldResetPassword
if let shouldResetPassword = form.shouldResetPassword {
self.shouldResetPassword = shouldResetPassword
}

self.updatedAt = Date()
self.createdAt = Date()
}

public func fill(form: BackendUserForm) {
public func fill(form: BackendUserForm, request: Request) throws {
name = form.name
email = form.email
role = form.role

// Only super admins can update roles
let rolesForUser = try Configuration.shared?.getRoleOptions(request.authedBackendUser().role) ?? [:]
if rolesForUser[form.role] != nil {
role = form.role
}

if let shouldResetPassword = form.shouldResetPassword {
self.shouldResetPassword = shouldResetPassword
}

updatedAt = Date()

if(!form.randomPassword) {
Expand Down
4 changes: 2 additions & 2 deletions Sources/AdminPanel/Models/BackendUsers/BackendUserForm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public struct BackendUserForm: Form {
let password: String
let sendMail: Bool
var randomPassword = false
let shouldResetPassword: Bool
var shouldResetPassword: Bool? = nil

public static let fieldset = Fieldset([
"name": StringField(
Expand Down Expand Up @@ -72,7 +72,7 @@ public struct BackendUserForm: Form {
shouldResetPassword = true
} else if validatedData["should_reset_password"] != nil {
shouldResetPassword = true
} else {
} else if validatedData["password"]?.string != nil {
shouldResetPassword = false
}
}
Expand Down
8 changes: 6 additions & 2 deletions Sources/AdminPanel/Resources/Views/BackendUsers/edit.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@
<div class="margin-vertical-sm">
#form:textgroup("name", backendUser.name, fieldset)
#form:emailgroup("email", backendUser.email, fieldset)
#form:selectgroup("role", roles, fieldset, defaultRole)
#if(backendUser) {
#form:selectgroup("role", roles, fieldset, backendUser.role)
} ##else() {
#form:selectgroup("role", roles, fieldset, defaultRole)
}

#if(#(backendUser)) {
#if(backendUser) {
} ##else() {
#form:checkboxgroup("send_mail", "true", fieldset)
}
Expand Down
4 changes: 4 additions & 0 deletions Sources/AdminPanel/Resources/Views/BackendUsers/index.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
</td>
<td class="text-center">#(user.role)</td>
<td class="text-center">

#allow(request, user.role) {
<a href="/admin/backend_users/edit/#(user.id)" class="btn btn-sm btn-default" data-tooltip="true" title="Edit details">
<span class="fa fa-pencil"></span>
<span class="sr-only">Edit details</span>
Expand All @@ -60,6 +62,8 @@
<span class="fa fa-times"></span>
<span class="sr-only">Delete user</span>
</a>
}

<td>
</tr>
}
Expand Down
8 changes: 8 additions & 0 deletions Sources/AdminPanel/Resources/Views/Emails/reset-password.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
To reset your password, click the following link:<br>
<a href="#(url)/admin/login/reset/#(token)">#(url)/admin/login/reset/#(token)</a>
</p>

<p>
If you can't use the click above, please copy paste the following into your browser:
<br>
#(url)/admin/login/reset/#(token)
</p>

<p><em>This reset password request will expire in #(expire) minutes.</em></p>

</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
<li class="list-group-heading">
Super admin
</li>
<li class="list-group-item #active(request, "/admin/backend_users", "/admin/backend_users/create", "/admin/backend_users/edit*")">
<a href="/admin/backend_users">
<i class="fa fa-street-view"></i>
Backend users
</a>
</li>
}

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

<li class="list-group-item #active(request, "/admin/backend_users", "/admin/backend_users/create", "/admin/backend_users/edit*")">
<a href="/admin/backend_users">
<i class="fa fa-street-view"></i>
Backend users
</a>
</li>
}
</ul>
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@

<div class="dropdown dropdown-user">
<button class="btn btn-transparent dropdown-toggle user__info-button" data-toggle="dropdown">
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)"/>
<span class="user__info-name">
#(request.storage.authedBackendUser.email)
<span class="caret"></span>
</span>
</button>
<div class="dropdown-menu dropdown-inverse animate-expand align-right">
<div class="dropdown-content">
<p class="dropdown-content__title">User</p>

<div class="user">
<div class="user__profile">
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)">
</div>
<div class="user__info">
<span class="user__info-name">
#(request.storage.authedBackendUser.name)
</span>
<span class="user__info-email">
#(request.storage.authedBackendUser.email)
</span>
</div>
</div>
<div class="user-actions">
<a href="/admin/backend_users/logout" class="btn btn-sm btn-transparent user__sign-out">
<i class="fa fa-sign-out"></i>
Sign out
</a>
<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">
<i class="fa fa-pencil"></i>
</a>
<div class="dropdown dropdown-user">
<button class="btn btn-transparent dropdown-toggle user__info-button" data-toggle="dropdown">
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)"/>
<span class="user__info-name">
#(request.storage.authedBackendUser.email)
<span class="caret"></span>
</span>
</button>
<div class="dropdown-menu dropdown-inverse animate-expand align-right">
<div class="dropdown-content">
<p class="dropdown-content__title">User</p>

<div class="user">
<div class="user__profile">
<img class="user__info-avatar img-responsive img-circle" src="#(request.storage.authedBackendUser.imageUrl)">
</div>
<div class="user__info">
<span class="user__info-name">
#(request.storage.authedBackendUser.name)
</span>
<span class="user__info-email">
#(request.storage.authedBackendUser.email)
</span>
</div>
</div>
<div class="user-actions">
<a href="/admin/backend_users/logout" class="btn btn-sm btn-transparent user__sign-out">
<i class="fa fa-sign-out"></i>
Sign out
</a>
<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">
<i class="fa fa-pencil"></i>
</a>
</div>
</div>
</div>
</div>
41 changes: 40 additions & 1 deletion Sources/AdminPanel/Support/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ public struct Configuration {
}

public var defaultRole: String {
return "admin"
for role in roles {
if role.isDefault {
return role.slug
}
}
return "user"
}

public init(drop: Droplet) throws {
Expand Down Expand Up @@ -125,4 +130,38 @@ public struct Configuration {

return roleArray
}

public func getRoleOrFail(_ slug: String) throws -> Role {
for role in roles {
if role.slug == slug {
return role
}
}

throw Abort.custom(status: .internalServerError, message: "The role \(slug) was not found")
}

public func getRoles(_ slug: String) -> [Role] {
var roles: [Role] = []

for role in self.roles {
// Add roles which is on level or below the slug input param
if role.slug == slug || roles.count > 0 {
roles.append(role)
}
}


return roles
}

public func getRoleOptions(_ slug: String) -> [String : String] {
var roles: [String : String] = [:]

for role in getRoles(slug) {
roles[role.slug] = role.title
}

return roles
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import VaporForms
import HTTP
import Vapor

extension Request {
public func authedBackendUser() throws -> BackendUser {

guard let backendUser: BackendUser = try auth.user() as? BackendUser else {
throw Abort.custom(status: .internalServerError, message: "The authed user is not a BackendUser")
}

return backendUser
}
}
Loading

0 comments on commit 07cd043

Please sign in to comment.