mumuki-domain 9.12.0 → 9.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d20f0f5d9cfe938c4a33f561f9e4df1e5e84ab18296fda644038b87166d631fc
4
- data.tar.gz: bf7adb112a37b84a8fb4f8fa7dc74db1c5df29dc0d8763005256e98e381b7951
3
+ metadata.gz: cce9f2ab048f758a4122c66f8a3da650a28c3a2ef10aefd8887a89091ba7a2af
4
+ data.tar.gz: c55a063f04e3ae7d32750db8b7f520a2bd3f8d37f4411201011fec953ee99079
5
5
  SHA512:
6
- metadata.gz: fbcc0dcdd8fd5134d463f61f18da8dfc872b7142f221f16ea3d99dac828bdbcf628d47b924559ac40e3224597955ad575720dc318b385297509cc3364b5c9897
7
- data.tar.gz: 4a2a358f2b888268d4193b0b9b50873702ac293430c26e5d64576f7c02b185fc4263cbc0b30c02758c611240e9646bb917277ed5ec37951521762db028f0fb52
6
+ metadata.gz: d203713ba3bcb38b7d36971a77718ff3887e82d51199e9423635f62a5a244d75433f5aefb7fbfe9c0994971b178dafc655eae03a4b8c9d48bcd0ccc655785441
7
+ data.tar.gz: c3b3db4bc2faac6b2ec976aa380fdd5ad203ee248f6fc96a7dccee55c58a794d7c7f11944be3ef75f311bd5f791e87590c676192194c3c4247e4dc53a51f67cf
@@ -0,0 +1,22 @@
1
+ class Organization::Status::Base
2
+
3
+ attr_reader :organization
4
+
5
+ implements :teacher_access_mode, :student_access_mode, :ex_student_access_mode, :outsider_access_mode, :validate!
6
+
7
+ def initialize(organization)
8
+ @organization = organization
9
+ end
10
+
11
+ def access_mode(user)
12
+ if user&.teacher_of? organization
13
+ teacher_access_mode(user)
14
+ elsif user&.student_of? organization
15
+ student_access_mode(user)
16
+ elsif user&.ex_student_of? organization
17
+ ex_student_access_mode(user)
18
+ else
19
+ outsider_access_mode(user)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ class Organization::Status::Disabled < Organization::Status::Base
2
+
3
+ def teacher_access_mode(user)
4
+ OrganizationAccessMode::Full.new user, organization
5
+ end
6
+
7
+ def student_access_mode(user)
8
+ OrganizationAccessMode::ReadOnly.new user, organization, :faqs, :profile, :exercises, :discussions
9
+ end
10
+
11
+ def ex_student_access_mode(user)
12
+ OrganizationAccessMode::ReadOnly.new user, organization, :faqs, :profile
13
+ end
14
+
15
+ def outsider_access_mode(user)
16
+ if organization.public?
17
+ OrganizationAccessMode::Gone.new user, organization
18
+ else
19
+ OrganizationAccessMode::Forbidden.new user, organization
20
+ end
21
+ end
22
+
23
+ def validate!(user = nil)
24
+ raise Mumuki::Domain::DisabledOrganizationError unless user
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,26 @@
1
+ class Organization::Status::Enabled < Organization::Status::Base
2
+
3
+ def teacher_access_mode(user)
4
+ OrganizationAccessMode::Full.new user, organization
5
+ end
6
+
7
+ def student_access_mode(user)
8
+ OrganizationAccessMode::Full.new user, organization
9
+ end
10
+
11
+ def ex_student_access_mode(user)
12
+ OrganizationAccessMode::ReadOnly.new user, organization, :faqs, :profile, :discussions, exercises: :submitted
13
+ end
14
+
15
+ def outsider_access_mode(user)
16
+ if organization.public?
17
+ OrganizationAccessMode::Full.new user, organization
18
+ else
19
+ OrganizationAccessMode::Forbidden.new user, organization
20
+ end
21
+ end
22
+
23
+ def validate!(_user = nil)
24
+ end
25
+
26
+ end
@@ -0,0 +1,27 @@
1
+ class Organization::Status::InPreparation < Organization::Status::Base
2
+
3
+ def teacher_access_mode(user)
4
+ OrganizationAccessMode::Full.new user, organization
5
+ end
6
+
7
+ def student_access_mode(user)
8
+ OrganizationAccessMode::ComingSoon.new user, organization
9
+ end
10
+
11
+ def ex_student_access_mode(user)
12
+ OrganizationAccessMode::Forbidden.new user, organization
13
+ end
14
+
15
+ def outsider_access_mode(user)
16
+ if organization.public?
17
+ OrganizationAccessMode::ComingSoon.new user, organization
18
+ else
19
+ OrganizationAccessMode::Forbidden.new user, organization
20
+ end
21
+ end
22
+
23
+ def validate!(user = nil)
24
+ raise Mumuki::Domain::UnpreparedOrganizationError unless user
25
+ end
26
+
27
+ end
@@ -30,4 +30,10 @@ module WithAssignments
30
30
  def assignment_for(user, organization=Organization.current)
31
31
  find_assignment_for(user, organization) || user.build_assignment(self, organization)
32
32
  end
33
+
34
+ def has_progress_for?(user, organization)
35
+ user.present? && find_assignment_for(user, organization).present?
36
+ end
37
+
38
+
33
39
  end
@@ -0,0 +1,32 @@
1
+ module WithOrganizationStatus
2
+
3
+ def status
4
+ @status ||= _status
5
+ end
6
+
7
+ def access_mode(user)
8
+ status.access_mode(user)
9
+ end
10
+
11
+ def validate_active!
12
+ status.validate!
13
+ end
14
+
15
+ def validate_active_for!(user)
16
+ status.validate!(user)
17
+ access_mode(user).validate_active!
18
+ end
19
+
20
+ private
21
+
22
+ def _status
23
+ if disabled?
24
+ Organization::Status::Disabled.new self
25
+ elsif in_preparation?
26
+ Organization::Status::InPreparation.new self
27
+ else
28
+ Organization::Status::Enabled.new self
29
+ end
30
+ end
31
+
32
+ end
@@ -7,6 +7,10 @@ module WithProgress
7
7
  progress_for(user, organization).completion_percentage
8
8
  end
9
9
 
10
+ def has_progress_for?(user, organization)
11
+ progress_for(user, organization).persisted?
12
+ end
13
+
10
14
  def dirty_progresses!
11
15
  Indicator.dirty_by_content_change! self
12
16
  end
@@ -6,6 +6,7 @@ class Organization < ApplicationRecord
6
6
  include Mumukit::Login::OrganizationHelpers
7
7
 
8
8
  include WithTargetAudience
9
+ include WithOrganizationStatus
9
10
 
10
11
  serialize :profile, Mumuki::Domain::Organization::Profile
11
12
  serialize :settings, Mumuki::Domain::Organization::Settings
@@ -0,0 +1,2 @@
1
+ module OrganizationAccessMode
2
+ end
@@ -0,0 +1,45 @@
1
+ class OrganizationAccessMode::Base
2
+ attr_reader :user, :organization
3
+
4
+ def initialize(user, organization)
5
+ @user = user
6
+ @organization = organization
7
+ end
8
+
9
+ def validate_active!
10
+ end
11
+
12
+ def faqs_here?
13
+ organization.faqs.present?
14
+ end
15
+
16
+ def submit_solutions_here?
17
+ false
18
+ end
19
+
20
+ def resolve_discussions_here?
21
+ false
22
+ end
23
+
24
+ def discuss_here?
25
+ organization.forum_enabled? && user.discusser_of?(organization) &&
26
+ user.trusted_as_discusser_in?(organization) && !user.banned_from_forum?
27
+ end
28
+
29
+ def show_discussion_element?
30
+ false
31
+ end
32
+
33
+ def show_content_element?
34
+ false
35
+ end
36
+
37
+ def validate_discuss_here!(_discussion)
38
+ raise Mumuki::Domain::ForbiddenError
39
+ end
40
+
41
+ def validate_content_here!(content)
42
+ raise Mumuki::Domain::ForbiddenError unless show_content?(content)
43
+ end
44
+ end
45
+
@@ -0,0 +1,5 @@
1
+ class OrganizationAccessMode::ComingSoon < OrganizationAccessMode::Forbidden
2
+ def validate_active!
3
+ raise Mumuki::Domain::UnpreparedOrganizationError
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ class OrganizationAccessMode::Forbidden < OrganizationAccessMode::Base
2
+ def validate_active!
3
+ raise Mumuki::Domain::ForbiddenError if organization.private? && user.present?
4
+ end
5
+
6
+ def faqs_here?
7
+ false
8
+ end
9
+
10
+ def profile_here?
11
+ false
12
+ end
13
+
14
+ def discuss_here?
15
+ false
16
+ end
17
+
18
+ def show_content?(_content)
19
+ false
20
+ end
21
+
22
+ end
@@ -0,0 +1,28 @@
1
+ class OrganizationAccessMode::Full < OrganizationAccessMode::Base
2
+ def profile_here?
3
+ true
4
+ end
5
+
6
+ def submit_solutions_here?
7
+ true
8
+ end
9
+
10
+ def show_discussion_element?
11
+ true
12
+ end
13
+
14
+ def resolve_discussions_here?
15
+ discuss_here?
16
+ end
17
+
18
+ def validate_discuss_here!(_discussion)
19
+ end
20
+
21
+ def show_content?(_content)
22
+ true
23
+ end
24
+
25
+ def show_content_element?
26
+ true
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ class OrganizationAccessMode::Gone < OrganizationAccessMode::Forbidden
2
+ def validate_active!
3
+ raise Mumuki::Domain::DisabledOrganizationError
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ class OrganizationAccessMode::ReadOnly < OrganizationAccessMode::Base
2
+ def initialize(user, organization, *global_scopes, **specific_scopes)
3
+ super user, organization
4
+ @scopes = global_scopes.map { |scope| [scope, :all] }.to_h.merge specific_scopes
5
+ end
6
+
7
+ def faqs_here?
8
+ has_scope(:faqs) && super
9
+ end
10
+
11
+ def profile_here?
12
+ has_scope(:profile)
13
+ end
14
+
15
+ def discuss_here?
16
+ has_scope(:discussions) && super
17
+ end
18
+
19
+ def validate_discuss_here!(discussion)
20
+ super(discussion) unless discussion&.initiator == user
21
+ end
22
+
23
+ def show_content?(content)
24
+ has_scope(:exercises) ||
25
+ (has_scope(:exercises, :submitted) && content.has_progress_for?(user, organization))
26
+ end
27
+
28
+ private
29
+
30
+ def has_scope(key, value = :all)
31
+ @scopes[key] == value
32
+ end
33
+ end
data/app/models/user.rb CHANGED
@@ -201,7 +201,7 @@ class User < ApplicationRecord
201
201
  # This is true only when this organization has the forum enabled and the user
202
202
  # has the discusser pseudo-permission and the discusser is trusted
203
203
  def can_discuss_in?(organization)
204
- organization.forum_enabled? && discusser_of?(organization) && trusted_as_discusser_in?(organization) && !banned_from_forum?
204
+ organization.access_mode(self).discuss_here?
205
205
  end
206
206
 
207
207
  def trusted_as_discusser_in?(organization)
@@ -283,6 +283,10 @@ class User < ApplicationRecord
283
283
  }
284
284
  end
285
285
 
286
+ def solved_any_exercises?(organization = Organization.current)
287
+ Assignment.exists?(organization: organization, submitter: self)
288
+ end
289
+
286
290
  def save_and_notify!
287
291
  save!
288
292
  notify_permissions_changed!
@@ -52,11 +52,6 @@ module Mumuki::Domain::Helpers::Organization
52
52
  Mumukit::Platform.application.organic_domain(name)
53
53
  end
54
54
 
55
- def validate_active!
56
- raise Mumuki::Domain::DisabledOrganizationError if disabled?
57
- raise Mumuki::Domain::UnpreparedOrganizationError if in_preparation?
58
- end
59
-
60
55
  ## API Exposure
61
56
 
62
57
  def to_param
@@ -16,6 +16,22 @@ module Mumuki::Domain
16
16
  false
17
17
  end
18
18
 
19
+ def ex_student_of?(*)
20
+ false
21
+ end
22
+
23
+ def ex_student_here?
24
+ false
25
+ end
26
+
27
+ def student_of?(*)
28
+ false
29
+ end
30
+
31
+ def student_here?
32
+ false
33
+ end
34
+
19
35
  def teacher_here?
20
36
  false
21
37
  end
@@ -28,7 +28,7 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
28
28
  end
29
29
 
30
30
  def forum_discussions_minimal_role
31
- (@forum_discussions_minimal_role || 'student').to_sym
31
+ (@forum_discussions_minimal_role || 'ex_student').to_sym
32
32
  end
33
33
 
34
34
  def disabled_from=(disabled_from)
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Domain
3
- VERSION = '9.12.0'
3
+ VERSION = '9.13.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-domain
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.12.0
4
+ version: 9.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-12 00:00:00.000000000 Z
11
+ date: 2021-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '7.9'
33
+ version: '7.11'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '7.9'
40
+ version: '7.11'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mumukit-assistant
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -265,6 +265,10 @@ files:
265
265
  - app/models/concerns/navigation/siblings_navigation.rb
266
266
  - app/models/concerns/navigation/terminal_navigation.rb
267
267
  - app/models/concerns/onomastic.rb
268
+ - app/models/concerns/organization/status/base.rb
269
+ - app/models/concerns/organization/status/disabled.rb
270
+ - app/models/concerns/organization/status/enabled.rb
271
+ - app/models/concerns/organization/status/in_preparation.rb
268
272
  - app/models/concerns/submittable/confirmable.rb
269
273
  - app/models/concerns/submittable/queriable.rb
270
274
  - app/models/concerns/submittable/questionable.rb
@@ -292,6 +296,7 @@ files:
292
296
  - app/models/concerns/with_name.rb
293
297
  - app/models/concerns/with_notifications.rb
294
298
  - app/models/concerns/with_number.rb
299
+ - app/models/concerns/with_organization_status.rb
295
300
  - app/models/concerns/with_pg_lock.rb
296
301
  - app/models/concerns/with_preferences.rb
297
302
  - app/models/concerns/with_profile.rb
@@ -336,6 +341,13 @@ files:
336
341
  - app/models/message.rb
337
342
  - app/models/notification.rb
338
343
  - app/models/organization.rb
344
+ - app/models/organization_access_mode.rb
345
+ - app/models/organization_access_mode/base.rb
346
+ - app/models/organization_access_mode/coming_soon.rb
347
+ - app/models/organization_access_mode/forbidden.rb
348
+ - app/models/organization_access_mode/full.rb
349
+ - app/models/organization_access_mode/gone.rb
350
+ - app/models/organization_access_mode/read_only.rb
339
351
  - app/models/preferences.rb
340
352
  - app/models/progress.rb
341
353
  - app/models/stats.rb