trackington 0.0.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.
- checksums.yaml +7 -0
- data/lib/trackington.rb +12 -0
- data/lib/trackington/app/core.rb +33 -0
- data/lib/trackington/app/projects.rb +175 -0
- data/lib/trackington/app/sprints.rb +101 -0
- data/lib/trackington/app/tasks.rb +121 -0
- data/lib/trackington/app/users.rb +107 -0
- data/lib/trackington/db/config.yml +21 -0
- data/lib/trackington/db/migrate/20160207202529_create_users.rb +7 -0
- data/lib/trackington/db/migrate/20160207203302_create_user_credentials.rb +11 -0
- data/lib/trackington/db/migrate/20160209100247_create_projects.rb +9 -0
- data/lib/trackington/db/migrate/20160209101604_create_project_roles.rb +10 -0
- data/lib/trackington/db/migrate/20160209153945_create_sprints.rb +11 -0
- data/lib/trackington/db/migrate/20160209154117_create_tasks.rb +18 -0
- data/lib/trackington/db/migrate/20160209165534_update_sprint_columns.rb +5 -0
- data/lib/trackington/db/migrate/20160209193650_update_tasks_references.rb +5 -0
- data/lib/trackington/db/migrate/20160209195016_update_tasks_column.rb +5 -0
- data/lib/trackington/db/models/credential.rb +9 -0
- data/lib/trackington/db/models/project.rb +10 -0
- data/lib/trackington/db/models/project_role.rb +12 -0
- data/lib/trackington/db/models/sprint.rb +11 -0
- data/lib/trackington/db/models/task.rb +13 -0
- data/lib/trackington/db/models/user.rb +9 -0
- data/lib/trackington/rake/task.rb +44 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 835a6b6162d41dd5040a9a3992a7ee3598ab7426
|
|
4
|
+
data.tar.gz: 828145201ee43eb13a64dedfd2bb7b924fdceb6c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bdfa7f6ca8d9b34bd37c01b6f74d7556062188a457fb7421d1cb0e9aa9be9d3a3db8942ebda2b9a7387417f7c0ba33b5eae85624dd56aee2b1ee423d7564f22d
|
|
7
|
+
data.tar.gz: 7dc50add501044e7e0fbc1c9686a98d99dbf9942d6fee963c4653456d6dcc266835d2780e30f163ece5be26826f2e2519d39edc90ec1d3ca2cf975e0b2546e7b
|
data/lib/trackington.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require_relative 'trackington/app/core'
|
|
2
|
+
require_relative 'trackington/app/projects'
|
|
3
|
+
require_relative 'trackington/app/sprints'
|
|
4
|
+
require_relative 'trackington/app/tasks'
|
|
5
|
+
require_relative 'trackington/app/users'
|
|
6
|
+
|
|
7
|
+
require_relative 'trackington/db/models/credential'
|
|
8
|
+
require_relative 'trackington/db/models/project'
|
|
9
|
+
require_relative 'trackington/db/models/project_role'
|
|
10
|
+
require_relative 'trackington/db/models/sprint'
|
|
11
|
+
require_relative 'trackington/db/models/task'
|
|
12
|
+
require_relative 'trackington/db/models/user'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
require_relative 'users'
|
|
5
|
+
require_relative 'projects'
|
|
6
|
+
|
|
7
|
+
module Trackington
|
|
8
|
+
class Application
|
|
9
|
+
attr_reader :users, :projects
|
|
10
|
+
|
|
11
|
+
def initialize(connection_config = nil)
|
|
12
|
+
@users = UserRepository.new
|
|
13
|
+
@projects = ProjectRepository.new
|
|
14
|
+
|
|
15
|
+
establish_connection(connection_config)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def establish_connection(config)
|
|
21
|
+
if config.nil?
|
|
22
|
+
config_path = File.expand_path('../../db/config.yml', __FILE__)
|
|
23
|
+
config = YAML.load(IO.read(config_path))
|
|
24
|
+
|
|
25
|
+
env = ENV['DB'] || 'development'
|
|
26
|
+
|
|
27
|
+
ActiveRecord::Base.establish_connection(config[env])
|
|
28
|
+
else
|
|
29
|
+
ActiveRecord::Base.establish_connection(config)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require_relative 'sprints'
|
|
2
|
+
|
|
3
|
+
module Trackington
|
|
4
|
+
class ProjectRepository
|
|
5
|
+
def create(user_id, project_information)
|
|
6
|
+
project = Models::Project.new(project_information)
|
|
7
|
+
project.save
|
|
8
|
+
|
|
9
|
+
project_role = Models::ProjectRole.new(user_id: user_id,
|
|
10
|
+
project_id: project.id,
|
|
11
|
+
role_type: :owner)
|
|
12
|
+
project_role.save
|
|
13
|
+
|
|
14
|
+
sprint = Models::Sprint.new(project_id: project.id, is_backlog: true)
|
|
15
|
+
sprint.save
|
|
16
|
+
|
|
17
|
+
project.id
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def get(project_id)
|
|
21
|
+
db_project = Models::Project.find(project_id)
|
|
22
|
+
|
|
23
|
+
Project.new(db_project.id,
|
|
24
|
+
db_project.title,
|
|
25
|
+
db_project.description,
|
|
26
|
+
db_project.public)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def all(user_id)
|
|
30
|
+
get_projects(user_id: user_id)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def public
|
|
34
|
+
get_projects(public: true)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def get_projects(params)
|
|
40
|
+
project_ids = Models::ProjectRole
|
|
41
|
+
.where(params)
|
|
42
|
+
.select(:project_id)
|
|
43
|
+
.map(&:project_id)
|
|
44
|
+
|
|
45
|
+
Models::Project.find(project_ids).map do |db_project|
|
|
46
|
+
Project.new(db_project.id, db_project.title, db_project.description,
|
|
47
|
+
db_project.public)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class Project
|
|
53
|
+
attr_reader :id, :title, :description, :public, :sprints
|
|
54
|
+
|
|
55
|
+
def initialize(id, title, description, public)
|
|
56
|
+
@id = id
|
|
57
|
+
@title = title
|
|
58
|
+
@description = description
|
|
59
|
+
@public = public
|
|
60
|
+
@sprints = SprintRepository.new(@id)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def add_user(project_user, user_to_add, type = nil)
|
|
64
|
+
check_user_role(project_user, 'owner')
|
|
65
|
+
|
|
66
|
+
type ||= 'contributor'
|
|
67
|
+
|
|
68
|
+
existing = Models::ProjectRole.where(user_id: user_to_add,
|
|
69
|
+
project_id: @id).first
|
|
70
|
+
|
|
71
|
+
return unless existing.nil?
|
|
72
|
+
|
|
73
|
+
new_role = Models::ProjectRole.new(user_id: user_to_add,
|
|
74
|
+
project_id: @id,
|
|
75
|
+
role_type: type)
|
|
76
|
+
|
|
77
|
+
new_role.save
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def remove_user(project_user, user_to_remove)
|
|
81
|
+
check_user_role(project_user, 'owner')
|
|
82
|
+
|
|
83
|
+
Models::ProjectRole.destroy_all(project_id: @id,
|
|
84
|
+
user_id: user_to_remove)
|
|
85
|
+
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def update_user(project_user, user, new_type)
|
|
90
|
+
check_user_role(project_user, 'owner')
|
|
91
|
+
|
|
92
|
+
role = Models::ProjectRole.where(project_id: @id, user_id: user).first
|
|
93
|
+
|
|
94
|
+
role.role_type = new_type
|
|
95
|
+
|
|
96
|
+
role.save
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def update(project_user, data)
|
|
100
|
+
check_user_role(project_user, 'owner')
|
|
101
|
+
|
|
102
|
+
@title = data[:title]
|
|
103
|
+
@description = data[:description]
|
|
104
|
+
@public = data[:public]
|
|
105
|
+
|
|
106
|
+
db_project = Models::Project.find(@id)
|
|
107
|
+
db_project.title = @title
|
|
108
|
+
db_project.description = @description
|
|
109
|
+
db_project.public = @public
|
|
110
|
+
db_project.save
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def current_sprint(project_user)
|
|
114
|
+
check_user_role project_user
|
|
115
|
+
|
|
116
|
+
@sprints.current
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def create_sprint(project_user, data)
|
|
120
|
+
check_user_role(project_user, 'owner')
|
|
121
|
+
|
|
122
|
+
@sprints.create(data)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def start_sprint(project_user)
|
|
126
|
+
check_user_role(project_user, 'owner')
|
|
127
|
+
|
|
128
|
+
@sprints.start_sprint
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def complete_sprint(project_user)
|
|
132
|
+
check_user_role(project_user, 'owner')
|
|
133
|
+
|
|
134
|
+
@sprints.complete_sprint
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def backlog(project_user)
|
|
138
|
+
check_user_role project_user
|
|
139
|
+
|
|
140
|
+
@sprints.backlog
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def user_is?(user_id, type)
|
|
144
|
+
role = Models::ProjectRole.where(project_id: @id, user_id: user_id).first
|
|
145
|
+
|
|
146
|
+
return false if role.nil?
|
|
147
|
+
|
|
148
|
+
return true if role.role_type == 'owner'
|
|
149
|
+
|
|
150
|
+
role.role_type == type
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def users
|
|
154
|
+
Models::Project.find(@id).project_roles.map do |role|
|
|
155
|
+
ProjectRole.new(role)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
def check_user_role(user_id, type = 'spectator')
|
|
162
|
+
fail 'User not in role.' unless user_is?(user_id, type)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class ProjectRole
|
|
167
|
+
attr_reader :user_id, :user_email, :type
|
|
168
|
+
|
|
169
|
+
def initialize(project_role)
|
|
170
|
+
@user_id = project_role.user_id
|
|
171
|
+
@user_email = project_role.user.email
|
|
172
|
+
@type = project_role.role_type
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require_relative '../db/models/user'
|
|
2
|
+
require_relative '../db/models/credential'
|
|
3
|
+
require_relative 'tasks'
|
|
4
|
+
|
|
5
|
+
module Trackington
|
|
6
|
+
class SprintRepository
|
|
7
|
+
def initialize(project_id)
|
|
8
|
+
@project_id = project_id
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create(data)
|
|
12
|
+
data[:project_id] = @project_id
|
|
13
|
+
sprint = Models::Sprint.new(data)
|
|
14
|
+
sprint.is_active = true if current.nil?
|
|
15
|
+
sprint.save
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def current
|
|
19
|
+
db_sprint = Models::Sprint.where(project_id: @project_id,
|
|
20
|
+
is_active: true).first
|
|
21
|
+
|
|
22
|
+
return db_sprint if db_sprint.nil?
|
|
23
|
+
|
|
24
|
+
Sprint.new(db_sprint)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get(sprint_id)
|
|
28
|
+
db_sprint = Models::Sprint.find(sprint_id)
|
|
29
|
+
Sprint.new(db_sprint)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def complete_sprint
|
|
33
|
+
return if current.nil?
|
|
34
|
+
|
|
35
|
+
current.tasks.move_to(backlog.id)
|
|
36
|
+
current.end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def start_sprint
|
|
40
|
+
project_sprints = Models::Sprint.where(project_id: @project_id)
|
|
41
|
+
next_sprint_db = project_sprints.where('start_time > ?', Date.today).first
|
|
42
|
+
|
|
43
|
+
return if next_sprint_db.nil?
|
|
44
|
+
|
|
45
|
+
next_sprint = Sprint.new(next_sprint_db)
|
|
46
|
+
|
|
47
|
+
backlog.tasks.move_to(next_sprint.id)
|
|
48
|
+
next_sprint.start
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def backlog
|
|
52
|
+
query = Models::Sprint.where(project_id: @project_id, is_backlog: true)
|
|
53
|
+
backlog = query.first
|
|
54
|
+
Sprint.new(backlog)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Sprint
|
|
59
|
+
attr_reader :id, :start_time, :end_time, :is_active, :is_backlog, :tasks
|
|
60
|
+
|
|
61
|
+
def initialize(sprint)
|
|
62
|
+
@id = sprint.id
|
|
63
|
+
@start_time = sprint.start_time
|
|
64
|
+
@end_time = sprint.end_time
|
|
65
|
+
@is_active = sprint.is_active
|
|
66
|
+
@is_backlog = sprint.is_backlog
|
|
67
|
+
@project_id = sprint.project_id
|
|
68
|
+
@tasks = TaskRepository.new(@id)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def start
|
|
72
|
+
sprint = Models::Sprint.find(@id)
|
|
73
|
+
sprint.is_active = true
|
|
74
|
+
sprint.save
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def end
|
|
78
|
+
sprint = Models::Sprint.find(@id)
|
|
79
|
+
sprint.is_active = false
|
|
80
|
+
sprint.save
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def add_task(user_id, data)
|
|
84
|
+
check_user_role user_id
|
|
85
|
+
data[:created_by] = user_id
|
|
86
|
+
@tasks.add(data)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def all
|
|
90
|
+
@tasks.all
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def check_user_role(user_id, role = 'spectator')
|
|
96
|
+
repo = ProjectRepository.new
|
|
97
|
+
project = repo.get(@project_id)
|
|
98
|
+
project.user_is?(user_id, role)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require_relative '../db/models/task'
|
|
2
|
+
|
|
3
|
+
module Trackington
|
|
4
|
+
class TaskRepository
|
|
5
|
+
STATUSES = %w(open in_progress resolved closed reopened)
|
|
6
|
+
PRIORITIES = %w(blocker critical major minor trivial)
|
|
7
|
+
TYPES = %w(bug improvement new_feature story task)
|
|
8
|
+
|
|
9
|
+
def initialize(sprint_id)
|
|
10
|
+
@sprint_id = sprint_id
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def move_to(sprint_id)
|
|
14
|
+
tasks = Models::Task.where(sprint_id: sprint_id)
|
|
15
|
+
|
|
16
|
+
tasks.each do |task|
|
|
17
|
+
task.sprint_id = sprint_id if active?(task.status)
|
|
18
|
+
task.save
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add(data)
|
|
23
|
+
data[:sprint_id] = @sprint_id
|
|
24
|
+
task = Models::Task.new(data)
|
|
25
|
+
task.save
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def all
|
|
29
|
+
Models::Task.where(sprint_id: @sprint_id).map do |db_task|
|
|
30
|
+
Task.new(db_task)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get(id)
|
|
35
|
+
db_task = Models::Task.where(sprint_id: @sprint_id, id: id).first
|
|
36
|
+
Task.new(db_task)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def status_types
|
|
40
|
+
STATUSES
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def priorities
|
|
44
|
+
PRIORITIES
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def types
|
|
48
|
+
TYPES
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def active?(status)
|
|
54
|
+
%w(in_progress reopened open).include? status
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Task
|
|
59
|
+
STATUSES = %w(open in_progress resolved closed reopened)
|
|
60
|
+
PRIORITIES = %w(blocker critical major minor trivial)
|
|
61
|
+
TYPES = %w(bug improvement new_feature story task)
|
|
62
|
+
|
|
63
|
+
attr_reader :id, :title, :description, :time_planned, :time_actual
|
|
64
|
+
attr_reader :priority, :task_type, :status, :assigned_to, :created_by
|
|
65
|
+
|
|
66
|
+
def initialize(db_task)
|
|
67
|
+
basic_properties(db_task)
|
|
68
|
+
status_properties(db_task)
|
|
69
|
+
person_properties(db_task)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def active?
|
|
73
|
+
%w(in_progress reopened open).include? @status
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def update(data)
|
|
77
|
+
db_task = Models::Task.find(@id)
|
|
78
|
+
|
|
79
|
+
data.each do |property, new_value|
|
|
80
|
+
db_task[property] = get_value(property, new_value) if property != :id
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
db_task.save
|
|
84
|
+
|
|
85
|
+
basic_properties(db_task)
|
|
86
|
+
status_properties(db_task)
|
|
87
|
+
person_properties(db_task)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def basic_properties(db_task)
|
|
93
|
+
@id = db_task.id
|
|
94
|
+
@title = db_task.title
|
|
95
|
+
@description = db_task.description
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def status_properties(db_task)
|
|
99
|
+
@time_planned = db_task.time_planned
|
|
100
|
+
@time_actual = db_task.time_actual
|
|
101
|
+
|
|
102
|
+
@priority = db_task.priority
|
|
103
|
+
@task_type = db_task.task_type
|
|
104
|
+
@status = db_task.status
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def person_properties(db_task)
|
|
108
|
+
@assigned_to = db_task.assigned_to
|
|
109
|
+
@created_by = db_task.created_by
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def get_value(property, value)
|
|
113
|
+
case property
|
|
114
|
+
when :status then STATUSES.index(value)
|
|
115
|
+
when :priority then PRIORITIES.index(value)
|
|
116
|
+
when :task_type then TYPES.index(value)
|
|
117
|
+
else value
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require_relative '../db/models/user'
|
|
2
|
+
require_relative '../db/models/credential'
|
|
3
|
+
|
|
4
|
+
module Trackington
|
|
5
|
+
class UserRepository
|
|
6
|
+
SALT_LENGHT = 50
|
|
7
|
+
SESSION_KEY_LENGTH = 50
|
|
8
|
+
|
|
9
|
+
def register(email, password)
|
|
10
|
+
check_existing email
|
|
11
|
+
|
|
12
|
+
user = Models::User.new
|
|
13
|
+
user.email = email
|
|
14
|
+
user.save
|
|
15
|
+
|
|
16
|
+
credential = create_credentials(user.id, password)
|
|
17
|
+
|
|
18
|
+
credential.session_key
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def user(session_key)
|
|
22
|
+
db_credential = Models::Credential.where(session_key: session_key).first
|
|
23
|
+
|
|
24
|
+
db_user = Models::User.find(db_credential.user_id)
|
|
25
|
+
|
|
26
|
+
User.new(db_user.id, db_user.email)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def login(email, password)
|
|
30
|
+
user = Models::User.where(email: email).first
|
|
31
|
+
|
|
32
|
+
fail "Email/password don't match" if user.nil?
|
|
33
|
+
|
|
34
|
+
credential = Models::Credential.where(user_id: user.id).first
|
|
35
|
+
|
|
36
|
+
check_credentials(credential, password)
|
|
37
|
+
|
|
38
|
+
credential.session_key = generate_string SESSION_KEY_LENGTH
|
|
39
|
+
|
|
40
|
+
credential.save
|
|
41
|
+
|
|
42
|
+
credential.session_key
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def logout(session_key)
|
|
46
|
+
credential = Models::Credential.where(session_key: session_key).first
|
|
47
|
+
|
|
48
|
+
return if credential.nil?
|
|
49
|
+
|
|
50
|
+
credential.session_key = nil
|
|
51
|
+
credential.save
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def count
|
|
55
|
+
Models::User.count
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def search(query)
|
|
59
|
+
Models::User.where('email like ?', "%#{query}%").map do |user|
|
|
60
|
+
User.new(user.id, user.email)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def check_credentials(credential, password)
|
|
67
|
+
expected = hash(credential.salt + password)
|
|
68
|
+
|
|
69
|
+
fail "Username/password don't match." if expected != credential.password
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def check_existing(email)
|
|
73
|
+
existing_user = Models::User.where(email: email).first
|
|
74
|
+
|
|
75
|
+
fail 'User already exists.' unless existing_user.nil?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def create_credentials(user_id, password)
|
|
79
|
+
salt = hash(generate_string(SALT_LENGHT))
|
|
80
|
+
credential = Models::Credential.new
|
|
81
|
+
credential.password = hash(salt + password)
|
|
82
|
+
credential.salt = salt
|
|
83
|
+
credential.session_key = generate_string SESSION_KEY_LENGTH
|
|
84
|
+
credential.user_id = user_id
|
|
85
|
+
credential.save
|
|
86
|
+
credential
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def hash(input)
|
|
90
|
+
Digest::SHA256.base64digest(input)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def generate_string(length)
|
|
94
|
+
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
|
|
95
|
+
(0...length).map { o[rand(o.length)] }.join
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class User
|
|
100
|
+
attr_reader :id, :email
|
|
101
|
+
|
|
102
|
+
def initialize(id, email)
|
|
103
|
+
@id = id
|
|
104
|
+
@email = email
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
development:
|
|
2
|
+
adapter: sqlite3
|
|
3
|
+
database: lib/db/development.sqlite3
|
|
4
|
+
pool: 5
|
|
5
|
+
timeout: 5000
|
|
6
|
+
|
|
7
|
+
# production:
|
|
8
|
+
# adapter: pg
|
|
9
|
+
# encoding: utf8
|
|
10
|
+
# reconnect: false
|
|
11
|
+
# database: somedatabase_dev
|
|
12
|
+
# pool: 5
|
|
13
|
+
# username: root
|
|
14
|
+
# password:
|
|
15
|
+
# socket: /var/run/mysqld/mysqld.sock
|
|
16
|
+
|
|
17
|
+
test: &test
|
|
18
|
+
adapter: sqlite3
|
|
19
|
+
database: lib/trackington/db/tmp/test.sqlite3
|
|
20
|
+
pool: 5
|
|
21
|
+
timeout: 5000
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class CreateTasks < ActiveRecord::Migration
|
|
2
|
+
def change
|
|
3
|
+
create_table :tasks do |t|
|
|
4
|
+
t.string :title
|
|
5
|
+
t.string :description
|
|
6
|
+
|
|
7
|
+
t.integer :time_planned
|
|
8
|
+
t.integer :time_actual
|
|
9
|
+
|
|
10
|
+
t.integer :priority # Blocker, Critical, Major, Minor, Trivial
|
|
11
|
+
t.integer :type # Epic, Bug, Improvement, New Feature, Story, Task
|
|
12
|
+
t.integer :status
|
|
13
|
+
|
|
14
|
+
t.integer :assigned_to # should be belongs_to :user
|
|
15
|
+
t.integer :created_by # should be belongs_to :user
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'active_record'
|
|
2
|
+
|
|
3
|
+
module Trackington
|
|
4
|
+
module Models
|
|
5
|
+
class Task < ActiveRecord::Base
|
|
6
|
+
enum status: [:open, :in_progress, :resolved, :closed, :reopened]
|
|
7
|
+
enum priority: [:blocker, :critical, :major, :minor, :trivial]
|
|
8
|
+
enum task_type: [:bug, :improvement, :new_feature, :story, :task]
|
|
9
|
+
|
|
10
|
+
belongs_to :sprint
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/tasklib'
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'active_record'
|
|
5
|
+
|
|
6
|
+
module Trackington
|
|
7
|
+
class RakeTask < ::Rake::TaskLib
|
|
8
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
namespace :trackington do
|
|
12
|
+
namespace :db do
|
|
13
|
+
task :migrate do
|
|
14
|
+
establish_connection
|
|
15
|
+
|
|
16
|
+
migrate
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def establish_connection
|
|
25
|
+
db_query = ENV['DB_QUERY']
|
|
26
|
+
|
|
27
|
+
db = URI.parse(db_query)
|
|
28
|
+
|
|
29
|
+
ActiveRecord::Base.establish_connection(
|
|
30
|
+
adapter: db.scheme == 'postgres' ? 'postgresql' : db.scheme,
|
|
31
|
+
host: db.host,
|
|
32
|
+
username: db.user,
|
|
33
|
+
password: db.password,
|
|
34
|
+
database: db.path[1..-1],
|
|
35
|
+
encoding: 'utf8')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def migrate
|
|
39
|
+
migrations_path = File.expand_path('../../db/migrate', __FILE__)
|
|
40
|
+
|
|
41
|
+
ActiveRecord::Migrator.migrate(migrations_path, nil)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: trackington
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Yoan Dinkov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-02-10 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Simple bug tracking system based on projects, sprints, tasks. (University
|
|
14
|
+
project)
|
|
15
|
+
email:
|
|
16
|
+
- yoandinkov@gmail.com
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- lib/trackington.rb
|
|
22
|
+
- lib/trackington/app/core.rb
|
|
23
|
+
- lib/trackington/app/projects.rb
|
|
24
|
+
- lib/trackington/app/sprints.rb
|
|
25
|
+
- lib/trackington/app/tasks.rb
|
|
26
|
+
- lib/trackington/app/users.rb
|
|
27
|
+
- lib/trackington/db/config.yml
|
|
28
|
+
- lib/trackington/db/migrate/20160207202529_create_users.rb
|
|
29
|
+
- lib/trackington/db/migrate/20160207203302_create_user_credentials.rb
|
|
30
|
+
- lib/trackington/db/migrate/20160209100247_create_projects.rb
|
|
31
|
+
- lib/trackington/db/migrate/20160209101604_create_project_roles.rb
|
|
32
|
+
- lib/trackington/db/migrate/20160209153945_create_sprints.rb
|
|
33
|
+
- lib/trackington/db/migrate/20160209154117_create_tasks.rb
|
|
34
|
+
- lib/trackington/db/migrate/20160209165534_update_sprint_columns.rb
|
|
35
|
+
- lib/trackington/db/migrate/20160209193650_update_tasks_references.rb
|
|
36
|
+
- lib/trackington/db/migrate/20160209195016_update_tasks_column.rb
|
|
37
|
+
- lib/trackington/db/models/credential.rb
|
|
38
|
+
- lib/trackington/db/models/project.rb
|
|
39
|
+
- lib/trackington/db/models/project_role.rb
|
|
40
|
+
- lib/trackington/db/models/sprint.rb
|
|
41
|
+
- lib/trackington/db/models/task.rb
|
|
42
|
+
- lib/trackington/db/models/user.rb
|
|
43
|
+
- lib/trackington/rake/task.rb
|
|
44
|
+
homepage: http://rubygems.org/gems/trackington
|
|
45
|
+
licenses:
|
|
46
|
+
- MIT
|
|
47
|
+
metadata: {}
|
|
48
|
+
post_install_message:
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
require_paths:
|
|
51
|
+
- lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
requirements: []
|
|
63
|
+
rubyforge_project:
|
|
64
|
+
rubygems_version: 2.4.5.1
|
|
65
|
+
signing_key:
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Trackington - bug tracking system. (University project)
|
|
68
|
+
test_files: []
|