* Prepare: relocate user suggestions
* Prepare: relocate users suggestion service -> query
* Organization query for orgs with above-average scores
* Rubocop
* Limit to last 3 weeks
* Tweak recent scope, limit to 5 orgs
* Onboarding routes are also always JSON
* Divide by zero makes NaN means
* Add Orgs suggester into suggestions
* Rubocop
* select distinct orgs
* Fix for weird edge-case with bad local data
* Include type_identifier in JSON payload
* Update follows API to allow org_ids as input
* Update onboarding front-end to distinguish users/orgs
* Fix: i18n issues
* Fix: type_identifier in json output
* Fix: distinct is weird
* Fix: JS linter
* Continue tweaking front-end
* Audit import order
* Cleanup @todo note
* Try renaming controller action
* Move Article average calculation to postgres and fix math
* Refactor decorated type_identifier
* Refactor SuggestProminent, return more orgs, fix spec math
* Use FeatureFlag for organization suggestions
* This might fix the jest
* Refresh an individual user's segmentation
* Refresh segment if creating a published article
* Quick refactor
* Refresh segment if update publishing
* Quick refactor
* Refresh segment if update user settings
* Refresh segments after user update + role change
* Using latest_article_updated_at
* Sidekiq uses JSON for arguments, needs basic types
* Fix test issues with last_updated_at and sidekiq params
* Tests update continues
* Consolidate dependencies
* Method names acknowledging manual exclusive
* Fix test name copypasta
* Rubocop
* Try to clarify Creator#series
* Try to avoid naming predicate
* Remove erroneously included helper
* Trying some models for audience segmentation
* AudienceSegment basics
* Attach AudienceSegment to DisplayAd
* Possibly use a DUS to populate AudienceSegments
* Add to display ad form UI
* Add to display ad API
* Refresh strategy for audience segments
* Add user_id to async ads query
* Maybe :testing -> :manual, for no-refresh segment
* Test & tweak segment refresh
* Testing audience_segment#refresh logic
* Coverage: testing human_readable
* Scope segment refresh to recently active users
* Tweak logic for when to refresh
* Tweak experience levels to match SettingsHelper
* Test for front-end logic
* Fix test, hope this helps coverage?
* Better test names
* One worker for all, many workers for each, perform_bulk
* Fix audience segment UI, needs to use id, not enum
* cron/schedule should RefreshAll
* Singular id in RefreshWorker
* chore: rubocop
* feat: rename the worker in accordance to our guidelines and to be more verbose
* refactor: move the NotificationsModeration service to be a users query, and move the constants out to new files
* refactor: removed subscribed_to_mod_roundrobin_notifications? which was only being used once in a test
* refactor: remove the aliass from the user method and add them to notification_setting + update references
* feat: remove initializeSponsorshipVisibility and related code
* feat: remove sponsorships from sidebar
* feat: remove sponsorships from the admin - route, controller, view, spec
* feat: remove the admin menu item
* feat: remove the i8n for admin sponsors controller
* feat: sponsorship decorator was not being used anywhere
* feat: sponsorship slack messenger was not being used anywhere
* feat: remove the sponsorship_headline that gets configures on the admin
* feat: remove the /sponsors page
* feat: remove renedring of single_sponsor partial and associated partials
* feat: remove the navigation link rake task for sponsors
* feat: remove sponsorship from tags
* feat: remove i8n constants used
* remove sponsor references in text to the privacy page
* feat: remove the sponsorship detail from the organization page
* feat: remove the sponsors css that was used for app/views/pages/sponsors.html.erb
* feat: remove the sponsorship i8n that was used in the slack messengers
* feat: swap out the decorators to use Article as an example
* feat: remove spec to show sponsors on home page
* feat: update the specs to use Article Decorator instead of the Sponsorship Decorator
* fix: use direct and not all
* fix: remove tests for tag sponsorship
* fix: remove organization sponsorship test
* feat: remove more i8n
* remove unused css from app/views/organizations/_sidebar_additional.html.erb
* feat: remove sponsorship relationship from tag and organization
* remove seed
* feat: remove all Sponsor related specs
* feat: remove model, associated i8n and specs
* feat: remove sponsor from navbar
* feat: add a guard clause if we're unable to constantinize the purchase_type
* feat; remove sponsorship related tests
* feat: remove sponsorship relationship
* feat: remov especs related to sponsorship
* feat: remove tag sponsorship validation
* feat: remove the sponsorship factory
* Make user_id optional for DisplayAdEvent
* Track when DisplayAd is visible to user
* Tidy up a bit
* Deleting a user account should nullify related DisplayAdEvents
* Update tests with new association details
* Try renaming moderator -> super_moderator
* Still finding 'moderator' words
* Fixes for failing specs
* Update test with new role name
* Update app/services/moderator/manage_activity_and_roles.rb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Remove sustaining member newsletter, and its settings
This removes the concept of sustaining memberships from the system,
and logic related to or dependent on it.
This does not remove the monthly_dues column from the users table (todo).
* Remove unused newsletter setting
Since nothing accesses the mailchimp_sustaining_members_id setting,
it's safe to remove.
* Use destroy rather than delete to ensure settings cache is cleared
We have a callback in Settings::Base to clear the cache after commit,
I assume it's useful to trigger that. This requires destroy, not
delete, to be called.
* Rename unsubscribe to remove_from_mailchimp_newsletters
* Permanently delete from mailchimp instead of unsubscribing
* Rename method and remove comment
* Don't use i18n because of error message
We don't want to use i18n here because e.title comes from the error response. If a Forem
was using a different locale and Mailchimp for newsletters, they would still receive the
error response in English (because of Mailchimp).
* Refactor and rename a bit
* Rename methods in tests accordingly
* Remove now moot test
* Rename method in other places it was previously called
* Remove unused translation, see 62fee247ee2565e4d3d14919a8636a76ce5ecc9f
* Fix typo and report error if not 404
* Adds data to the member column in Member Index View
* Adds roles, statuses, and latest activity to Member Index views
* Adds the list of orgs a user belongs to in Member Index view
* Updates the image URL to link to each users member detail view
* Adds comment_suspended to user current_status and makes roles prettier
* Fixes bullet warning and encapsulates org logic in method
* Properly displays today and yesterday in words
* Refactors #current_organizations to use ternary
* Updates user.rb Member Index View-related methods
* Adjusts the styling of user roles and adds tooltip to roles
* Updates Member Index View to be mobile-friendly
* Updates userIndexView.spec.js
* Updates capitalization within userIndexView.spec.js
* Updates Member Index View per mobile designs and feedback
* Adds member status logic inline with SVGs
* Updates the status column for mobile layout
* Adjust current_role tooltips for Member Index View
* Adds organization name tooltip to member orgas
* Adds organization pics to Member Index View and cleans up helpers
* Addresses PR review feedback (Thanks, Suzanne!)
* Uses CSS in place of SVGs for member statuses
* Adds E2E test for and removes link to org page from Member Index View
* Addresses PR feedback comments by refactoring Member Index View code
* Removes leftover code in user.rb
* Update method that tooltips rely on
* Spells regular correctly :
* Adds a spec that tests Admin::UsersHelper#format_last_activity_timestamp
* Adjusts #cascading_high_level_roles logic and roles
* Adds a spec for #cascading_high_level_roles
* Adds a #last_activity spec to the User model
* Adjusts code a bit per PR feedback. Thanks, Ridhwana! :)
* Updates specs for Member Index View helpers
* Adds Timecop.freeze to help with timestamp failure in user_spec.rb
Prior to this commit, when we change attributes for a user we might
resave each article. The purpose of the resave is to update some of the
cached attributes of an article.
This removes some redundant code. The following removed code has
an `article.save` call. Which, the callbacks in the article (see below)
already clear the cache.
```ruby
def resave_articles
articles.find_each do |article|
if article.path
cache_bust = EdgeCache::Bust.new
cache_bust.call(article.path)
cache_bust.call("#{article.path}?i=i")
end
article.save
end
end
```
8e6981aac5/app/models/article.rb (L164)8e6981aac5/app/models/article.rb (L881-L888)
This was discovered in triaging forem/forem#17041
In looking at forem/forem#16787, it felt like we would benefit from a
similar approach as we adopted for nullifying blank strings.
This refactor helps pave the way for a "normalize_text_for" method (or
some such thing; naming things is hard).
This change also involved introducing a `describe` block into the
associated spec.
* Refactoring cached_followed_tags
This refactor consolidates two queries and a loop into a single query.
One thing that is unclear is if we're ever really clearing the cache of
the user by id?
What follows is un-related to the refactor but appears to be related to #14937.
> First, I see we set a cache here:
>
> ebdaaaf15b/app/decorators/user_decorator.rb (L23-L34)
>
> But when I look at what busts the user cache, it doesn’t look like we’re busting it for the above cached location:
>
> ebdaaaf15b/app/services/edge_cache/bust_user.rb (L3-L22)
>
> What if anything am I missing in regards to cache busting?
* Adding some deprecated methods
* Updating documentation
* Bump for travis
* Bump for travis
* Updating comments to fix confusion
NOTE: I might be introducing more confusion, but at least
I'm addressing the prior confusion.
* Bump for travis
* Updating so we don't cache ActiveRecord objects
* Selecting only applicable attributes for caching
* Apply suggestions from code review
Co-authored-by: Michael Kohl <citizen428@forem.com>
* Adjusting code based on feedback
* Bump for travis
* Bump for travis
* Update app/decorators/user_decorator.rb
Co-authored-by: Michael Kohl <citizen428@forem.com>
Co-authored-by: Michael Kohl <citizen428@forem.com>
This change restores setting usernames to something less obnoxious.
Prior to this commit, I would on occassion get the following error in
seeds:
```shell
❯ bin/rails db:seed
Seeding with multiplication factor: 1
1. Creating Organizations.
2. Creating 10 Users.
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Username is too long (maximum is 30 characters)
./forem/db/seeds.rb:67:in `block (2 levels) in <main>'
./forem/db/seeds.rb:60:in `times'
./forem/db/seeds.rb:60:in `block in <main>'
./forem/app/lib/seeder.rb:30:in `create_if_none'
./forem/db/seeds.rb:57:in `<main>'
<internal:~/.rbenv/versions/3.0.2/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
<internal:~/.rbenv/versions/3.0.2/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
-e:1:in `<main>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)
```
Related to work done in #16067
* Refactoring to add helper method
Prior to this commit, we made view level calls to service modules. This
refactor provides convenience methods on the model.
Furthermore, it addresses a few Rubocop violations that "come along for
the ride."
* Ensuring cached entity squaks like User
* Fixing broken spec
* Fixing typo
* Remove slash characters from user supplied user search input
Prevents an error when the search term includes '\'
PG::SyntaxError: ERROR: syntax error in tsquery
https://app.honeybadger.io/projects/66984/faults/79391397
I had originally thought to add this cleanup to Search::Username but
decided to move it as close to the generated (invalid) query as
possible to prevent alternate paths finding their way here.
* Add spec
Since there's no existing tests for the scope - I put the test code on
the caller (Search::Username) rather than the model (User), this seems reasonable.
* When the term is empty (or only slashes) just return null relation
* Handle nil input (search for nothing) correctly
One of the request specs sends a username search with no query, so we
can't call nil.delete or nil.empty?, use blank? of empty?
* Refactoring questions asked of user
In this pull request, I'm extracting and normalizing role-based
questions asked of the user.
Prior to this commit, our codebase has asked two very similar questions
of our user model:
- `user.has_role?(:admin)`
- `user.admin?`
In asking `has_role?(:admin)` we are relying on implementation details
of the rolify gem. In addition, the `has_role?` question asked
throughout controllers or views means that it's harder to create
hieararchies of permissions.
In favoring `user.admin?` as our question, we can use that indirection
as an opportunity to discuss and decide "Should someone with the
`:super_admin` role be `user.admin? == true`?"
The details of this commit is to do three primary things:
1. Ask the `has_role?` questions in "one place" in the code (e.g. the
`Authorizer` module)
2. Extract the role based questions that are on the `User` model and
provde backwards compatable delegation.
3. Structure the code so that it's harder to accidentally call
`user.has_role?` (e.g., make `User#has_role?` and `User#has_any_role?`
private).
This is related to #15624 and the updates are informed by discussion in
PR #15691. This commit supplants #15691.
* Refactoring the liquid tag policy tests
* Fixing typo
* Bump for travis
* Consolidating role query logic
Prior to this commit, we had two logically identical chunks of code.
With this commit, we consolidate that logic into a single method. In
addition, we remove one place where the application knows about the
roles implementation.
Loosely related to #15624.
* Bump for travis
* Remove reactions to a user when deleting the user
Fixes#15245
---
I have no idea why `create(:vomit_reaction, reactable: user)` gave a
validation error about category being invalid, but `build().save`
worked fine.
* Move relation details to reaction scope `for_user`
Add a user method to access this by passing self to reaction scope
* Create a moderator when flagging user in factory
This might be a missing requirement in the reactions factory - but
this suppresses an error about invalid category I was getting when
setting a privileged reaction on the user via
create(:vomit_reaction, reactable: user)
Everywhere else it looks like we do this with `user: moderator` (where
there's a trusted user in the surrounding context).
* Move trusted user requirement into vomit_reaction factory
* Add a data update script to remove reactions to deleted users
This cleans up the remaining invalid references and should make the
change in #15249 obsolete (i.e. we don't need to limit the view to
exclude items that no longer exist).
* User decorator (and spec) should use `trusted?`
Fixes a few issues seen in an rspec run that show as:
DEPRECATION WARNING: User#trusted is deprecated, favor
User#trusted? (called from config_body_class at
/opt/apps/forem/app/decorators/user_decorator.rb:58)
And here:
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:112
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:121
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:130
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:139
* prefer User trusted? to trusted
DEPRECATION WARNING: User#trusted is deprecated, favor
User#trusted? (called from permissions at
/opt/apps/forem/app/models/rating_vote.rb:25)
* Prefer trusted? to trusted in user spec
* Use warned? rather than warned in admin article partial
* use trusted? rather than trusted in moderator requests spec
* Prefer trusted? to trusted in moderations controller
* Prefer trusted? to trusted in moderations view
* User auditable? should call trusted? and not trusted
Deprecations go rolling right along.
* Invert guard clause logic to be positive
The original "return unless multiple negated conditions hold" guard
was cumbersome.
Invert to return if any of the exceptions apply, namely:
- this is a comment or readinglist rating (rather than explicit),
allowed for all
- this rating is from a moderator/trusted user (allowed)
- this rating is offered by the article's author (allowed)
I had intended to also remove the safe navigation operators (since it
wasn't clear why there would be a null user or null article, as
rating_vote joins users to articles with a score), but the builtin
validation tests (is expected to validate ...) build objects with
missing attributes, and raise errors when the spec is run.
* Extracting cross-model uniqueness validator
Prior to this commit, we had somewhat duplicated logic across four
models. In adding this validator we're consolidating the logic and
tidying up each of the other models; letting the validator know which
models are part of the "uniqueness gang."
* Adding conditional test for validator
* Bump for travis
* Apply suggestions from code review
Co-authored-by: Michael Kohl <citizen428@forem.com>
Co-authored-by: Michael Kohl <citizen428@forem.com>
* Refactoring to use StringAttributeCleaner
In #15281, we introduced the StringAttributeCleaner. Let's use it!
* Adding StringAttributeCleaner for User properties
* Parameterizing callback for attribute cleaning
* Reading and applying the example for attribute cleaner
`User#trusted?` is more Ruby idiomatic than `User#trusted`. This helps
align the various "User#question?" methods.
I've added a deprecation warning, but don't believe that this is active
in the code-base.
Given that we have the roles of `:tech_admin`, `:admin`, and
`:super_admin`, I don't want the surprise of assuming that `user.admin?`
means that they have the role of `:admin`.
* Refactoring to use scope
Prior to this commit, four methods had similar purpose but different
implementations. This commit normalizes that and extracts a few
`ActiveRecord::Base` scopes.
Related to #15624
* Fixing typo and tests
* Refactoring Spam Handler
There's considerable repeated logic between checking spam for an article
and spam for a comment and user.
This attempts to send things through channels that are similar and close
in organization.
* Fixing broken spec
* Fixing spec around recent user
* Update app/models/reaction.rb
Co-authored-by: Michael Kohl <citizen428@forem.com>
* Update app/models/reaction.rb
Co-authored-by: Michael Kohl <citizen428@forem.com>
* Consolidating new user query logic
Prior to this commit there were two separate queries around new user
logic. With this commit, we're changing the logic to repurpose a site
wide setting.
* Generalizing a previously specific message
* Fixing method name
As part of a recommended refactor, I extracted a method, then renamed
it. I failed to account for that renaming.
This commit fixes that.
Co-authored-by: Michael Kohl <citizen428@forem.com>
Prior to this commit, we trusted all user profiles. There are folks
using DEV.to profiles to help with their spam efforts.
With this commit, we're trying to thwart their efforts.
Closesforem/rfcs#334
* Favoring delete_all on user relationships
Prior to this commit, several of the user's "has_many" were marked as
`depenedent: :destroy`.
In the case of :destroy, ActiveRecord instantiates each object and then
runs destroy. Whereas in the case of :delete, ActiveRecord issues a SQL
command to delete the related files.
It is often "safer" to use :destroy, as it guarantees that you'll
instantiate the record and run it's callbacks. But sometimes you have
to go with the speed of SQL.
And while not directly related to #15424 it is representative of our
callback ecosystem creating some unexpected computational loads.
Related to #15442 and #15424
* Noting models that user no longer cascade destroys
* Remove Connect
* Remove more Connect specs
* Remove a lot more Connect code
* 🚮
* It all has to go
* Explicitly add httpclient
* Update application layout
* Remove messages association from User
* Start fixing specs
* reintroduce util function and refactor references
* Remove Connect Cypress test
* Fix more specs
* Remove Connect from listings
* Ignore contact_via_connect column on listings
* Remove contact_via_connect usages
* Ignore mod_chat_channel_id on tags
* Drop Connect tables
* Remove email_connect_messages from user notification settings
* Re-add httpclient 2.8.3
This was mistakenly removed as a merge conflict
* Don't need to exclude removed chat channel file
* Remove unneeded style for chat channels
* Remove unneeded channel list prop type
* Remove chat channels index/connect-link from getPageEntries
* Re-add comment from httpclient in Gemfile
* Remove connect references from mailers
Tag Moderators no longer have a chat channel
No longer will users be notified about new messages (there won't be
any)
No longer will users be notified about channel invites (you can't
invite anyone anymore)
* Don't configure Pusher and remove PUSHER_* from .env_sample
since it's removed from gemfile, the Pusher constant will not resolve, if this is
configured in the environment variables we'll fail to boot.
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Dan Uber <dan@forem.com>