mirror of https://github.com/gophish/gophish
Adding handling for campaign events
Cleaned up user import button Cleaning up modal interfacing Added ability to set result statuspull/24/head
parent
efec86ae56
commit
49da412538
|
@ -36,6 +36,17 @@ func (c *Campaign) Validate() (string, bool) {
|
|||
return "", true
|
||||
}
|
||||
|
||||
func (c *Campaign) UpdateStatus(s string) error {
|
||||
// This could be made simpler, but I think there's a bug in gorm
|
||||
return db.Table("campaigns").Where("id=?", c.Id).Update("status", s).Error
|
||||
}
|
||||
|
||||
func (c *Campaign) AddEvent (e Event) error {
|
||||
e.CampaignId = c.Id
|
||||
e.Time = time.Now()
|
||||
return db.Debug().Save(&e).Error
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
Id int64 `json:"-"`
|
||||
CampaignId int64 `json:"-"`
|
||||
|
@ -43,12 +54,16 @@ type Result struct {
|
|||
Status string `json:"status" sql:"not null"`
|
||||
}
|
||||
|
||||
func (r *Result) UpdateStatus(s string) error {
|
||||
return db.Debug().Table("results").Where("id=?", r.Id).Update("status", s).Error
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Id int64 `json:"-"`
|
||||
CampaignId int64 `json:"-"`
|
||||
Email string `json:"email"`
|
||||
Time time.Time `json:"time"`
|
||||
Message time.Time `json:"message"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// GetCampaigns returns the campaigns owned by the given user.
|
||||
|
@ -81,10 +96,10 @@ func GetCampaign(id int64, uid int64) (Campaign, error) {
|
|||
// PostCampaign inserts a campaign and all associated records into the database.
|
||||
func PostCampaign(c *Campaign, uid int64) error {
|
||||
// Fill in the details
|
||||
c.UserId = uid
|
||||
c.CreatedDate = time.Now()
|
||||
c.CompletedDate = time.Time{}
|
||||
c.Status = QUEUED
|
||||
c.Events = append(c.Events)
|
||||
// Check to make sure all the groups already exist
|
||||
for i, g := range c.Groups {
|
||||
c.Groups[i], err = GetGroupByName(g.Name, uid)
|
||||
|
@ -113,27 +128,26 @@ func PostCampaign(c *Campaign, uid int64) error {
|
|||
Logger.Println(err)
|
||||
return err
|
||||
}
|
||||
err = c.AddEvent(Event{Message:"Campaign Created"})
|
||||
if err != nil {
|
||||
Logger.Println(err)
|
||||
}
|
||||
// Insert all the results
|
||||
for _, g := range c.Groups {
|
||||
// Insert a result for each target in the group
|
||||
for _, t := range g.Targets {
|
||||
r := Result{Email: t.Email, Status: "Unknown", CampaignId: c.Id}
|
||||
c.Results = append(c.Results, r)
|
||||
err := db.Save(&r).Error
|
||||
if err != nil {
|
||||
Logger.Printf("Error adding result record for target %s\n", t.Email)
|
||||
Logger.Println(err)
|
||||
}
|
||||
c.Results = append(c.Results, r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateCampaignStatus(c *Campaign, s string) error {
|
||||
// This could be made simpler, but I think there's a bug in gorm
|
||||
return db.Table("campaigns").Where("id=?", c.Id).Update("status", s).Error
|
||||
}
|
||||
|
||||
//DeleteCampaign deletes the specified campaign
|
||||
func DeleteCampaign(id int64) error {
|
||||
// Delete all the campaign results
|
||||
|
|
|
@ -57,6 +57,7 @@ func Setup() error {
|
|||
db.CreateTable(GroupTarget{})
|
||||
db.CreateTable(Template{})
|
||||
db.CreateTable(SMTP{})
|
||||
db.CreateTable(Event{})
|
||||
db.CreateTable(Campaign{})
|
||||
//Create the default user
|
||||
init_user := User{
|
||||
|
|
|
@ -128,3 +128,23 @@
|
|||
.dropdown-menu > li > a {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.btn-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.btn-file input[type=file] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
font-size: 999px;
|
||||
text-align: right;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
background: white;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
|
@ -35,6 +35,19 @@ app.config(function($routeProvider) {
|
|||
})
|
||||
});
|
||||
|
||||
app.filter('cut', function() {
|
||||
return function(value, max, tail) {
|
||||
if (!value) return '';
|
||||
max = parseInt(max, 10);
|
||||
truncd = []
|
||||
for(var i=0; i < Math.min(value.length,max); i++) {
|
||||
if (i == max-1) truncd.push("...")
|
||||
else truncd.push(value[i].email);
|
||||
}
|
||||
return truncd;
|
||||
};
|
||||
});
|
||||
|
||||
// Example provided by http://docs.angularjs.org/api/ng/type/ngModel.NgModelController
|
||||
app.directive('contenteditable', function() {
|
||||
return {
|
||||
|
@ -59,9 +72,9 @@ app.directive('contenteditable', function() {
|
|||
var html = element.html();
|
||||
// When we clear the content editable the browser leaves a <br> behind
|
||||
// If strip-br attribute is provided then we strip this out
|
||||
if (attrs.stripBr && html == '<br>') {
|
||||
html = '';
|
||||
}
|
||||
//if (attrs.stripBr && html == '<br>') {
|
||||
// html = '';
|
||||
//}
|
||||
ngModel.$setViewValue(html);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,10 @@ var CampaignModalCtrl = function($scope, $modalInstance) {
|
|||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
$scope.ok = function(campaign) {
|
||||
$modalInstance.dismiss("")
|
||||
$scope.saveCampaign(campaign)
|
||||
}
|
||||
};
|
||||
|
||||
app.controller('CampaignResultsCtrl', function($scope, CampaignService, GroupService, ngTableParams, $http, $window) {
|
||||
|
@ -333,7 +337,6 @@ var GroupModalCtrl = function($scope, $modalInstance, $upload) {
|
|||
}).progress(function(evt) {
|
||||
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
|
||||
}).success(function(data, status, headers, config) {
|
||||
// file is uploaded successfully
|
||||
angular.forEach(data, function(record, key) {
|
||||
$scope.group.targets.push({
|
||||
email: record.email
|
||||
|
@ -451,6 +454,10 @@ var TemplateModalCtrl = function($scope, $modalInstance) {
|
|||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
$scope.ok = function(template) {
|
||||
$modalInstance.dismiss('')
|
||||
$scope.saveTemplate(template)
|
||||
};
|
||||
};
|
||||
|
||||
app.controller('SettingsCtrl', function($scope, $http, $window) {
|
||||
|
|
|
@ -39,5 +39,5 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="saveTemplate(template)" data-dismiss="modal">Save Template</button>
|
||||
<button type="button" class="btn btn-primary" ng-click="ok(template)" data-dismiss="modal">Save Template</button>
|
||||
</div>
|
||||
|
|
|
@ -10,12 +10,11 @@
|
|||
<div class="form-group">
|
||||
<input type="text" class="form-control" ng-model="group.name" placeholder="Group name" id="name" autofocus/>
|
||||
</div>
|
||||
<input type="file" ng-file-select="onFileSelect($files)">
|
||||
<fieldset disabled>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-danger"><i class="fa fa-plus"></i> Bulk Import Users (Coming Soon!)</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<span class="btn btn-danger btn-file" tooltip="Supports CSV files" tooltip-placement="right"><i class="fa fa-plus"></i> Bulk Import Users
|
||||
<input type="file" ng-file-select="onFileSelect($files)">
|
||||
</span>
|
||||
</div>
|
||||
<label class="control-label" for="users">Users:</label>
|
||||
<form ng:submit="addTarget()">
|
||||
<div class="input-group">
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
<tr ng-repeat="group in $data" class="editable-row">
|
||||
<td data-title="'Name'" sortable="'name'" class="col-sm-1">{{group.name}}</td>
|
||||
<td data-title="'Members'" class="col-sm-2">
|
||||
<span ng-repeat="target in group.targets">
|
||||
{{target.email}}{{$last ? '' : ', '}}
|
||||
<span ng-repeat="target in group.targets | cut:5 track by $index ">
|
||||
{{target}}{{$last ? '' : ', '}}
|
||||
</span>
|
||||
<div class="btn-group" style="float: right;">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle edit-button" data-toggle="dropdown">
|
||||
|
@ -49,7 +49,7 @@
|
|||
<li><a ng-click="editGroup(group)">Edit</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li><a ng-click="deleteGroup(group)" ng-href="#">Delete</a>
|
||||
<li><a ng-click="deleteGroup(group)">Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@ func (w *Worker) Start() {
|
|||
|
||||
func processCampaign(c *models.Campaign) {
|
||||
Logger.Printf("Worker received: %s", c.Name)
|
||||
err := models.UpdateCampaignStatus(c, models.IN_PROGRESS)
|
||||
err := c.UpdateStatus(models.IN_PROGRESS)
|
||||
if err != nil {
|
||||
Logger.Println(err)
|
||||
}
|
||||
|
@ -58,7 +58,17 @@ func processCampaign(c *models.Campaign) {
|
|||
err := e.Send(c.SMTP.Host, auth)
|
||||
if err != nil {
|
||||
Logger.Println(err)
|
||||
err = t.UpdateStatus("Error")
|
||||
if err != nil {
|
||||
Logger.Println(err)
|
||||
}
|
||||
} else {
|
||||
err = t.UpdateStatus("Email Sent")
|
||||
if err != nil {
|
||||
Logger.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Printf("Sending Email to %s\n", t.Email)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue