Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(accessLogExport)!: create new AccessLogExportTask to generate a csv of access logs TASK-871 #5258

Merged
merged 17 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,22 @@
/jsapp/ @magicznyleszek
/patches/ @p2edwards
/static/ @magicznyleszek
/webpack/ @magicznyleszek
/.babelrc.json @magicznyleszek
/.browserlistrc @magicznyleszek
/.eslintignore @magicznyleszek
/.eslintrc.js @magicznyleszek
/.node-version @magicznyleszek
/.nvmrc @magicznyleszek
/.prettierrc.js @magicznyleszek
/.stylelintrc.js @magicznyleszek
/.swcrc @magicznyleszek
/.coffeelnt.json @magicznyleszek
/package-lock.json @magicznyleszek
/package.json @magicznyleszek
/tsconfig.json @magicznyleszek
/static/js/ @magicznyleszek @p2edwards
/test/ @magicznyleszek @p2edwards
/webpack/ @magicznyleszek @p2edwards
/.babelrc.json @magicznyleszek @p2edwards
/.browserslistrc @magicznyleszek @p2edwards
/.eslintignore @magicznyleszek @p2edwards
/.eslintrc.js @magicznyleszek @p2edwards
/.node-version @magicznyleszek @p2edwards
/.nvmrc @magicznyleszek @p2edwards
/.prettierrc.js @magicznyleszek @p2edwards
/.stylelintrc.js @magicznyleszek @p2edwards
/.swcrc @magicznyleszek @p2edwards
/.coffeelint.json @magicznyleszek @p2edwards
/package-lock.json @magicznyleszek @p2edwards
/package.json @magicznyleszek @p2edwards
/tsconfig.json @magicznyleszek @p2edwards

# Billing
/jsapp/js/account/ @jamesrkiger
Expand All @@ -64,18 +66,25 @@
# Default owner
/dependencies/ @jnm @noliveleger
/hub/ @jnm @noliveleger
/hub/tests/ @jnm @noliveleger
/kobo/ @jnm @noliveleger
/kobo/apps/audit_log/ @rgraber
/kobo/apps/subsequences/ @Guitlle
/kpi/ @jnm @noliveleger
/test/ @jnm @noliveleger
/kpi/tests/ @jnm @noliveleger
/.coveragerc @jnm
/.dockerignore @jnm @noliveleger
/format-python.sh @noliveleger
/manage.py @jnm @noliveleger
/pip-compile.sh @jnm @noliveleger
/pyproject.toml @jnm @noliveleger

# Django Static Templates, HTML, JS, CSS
/kobo/apps/accounts/templates/ @magicznyleszek @p2edwards @jnm @noliveleger
/kpi/templates/ @magicznyleszek @p2edwards @jnm @noliveleger
/kpi/static/css/ @magicznyleszek @p2edwards
_registration.scss @magicznyleszek @p2edwards




Expand All @@ -84,7 +93,9 @@

/docker/ @bufke @jnm @noliveleger
/scripts/ @bufke @jnm @noliveleger
/scripts/*.js @magicznyleszek @p2edwards
/.github/ @bufke @jnm @noliveleger @magicznyleszek
/.github/workflows/npm-test.yml @bufke @jnm @noliveleger @magicznyleszek @p2edwards
/.gitlab-ci.yml @bufke
/Dockerfile @bufke @jnm @noliveleger

Expand All @@ -95,8 +106,8 @@
#### Documentation section
/CONTRIBUTING.md @Akuukis @magicznyleszek @noliveleger
/README.md @Akuukis @jnm @magicznyleszek @noliveleger
/.github/CODEOWNERS.md @Akuukis @jnm @noliveleger @magicznyleszek
/.github/FUNDING.md @Akuukis @jnm @noliveleger @magicznyleszek
/.github/CODEOWNERS @Akuukis @jnm @noliveleger @magicznyleszek
/.github/FUNDING.yml @Akuukis @jnm @noliveleger @magicznyleszek
/.github/ISSUE_TEMPLATE.md @Akuukis @jnm @noliveleger @magicznyleszek
/.github/PULL_REQUEST_TEMPLATE.md @Akuukis @jnm @noliveleger @magicznyleszek

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# KPI

[![Python Build Status](https://github.com/kobotoolbox/kpi/workflows/pytest/badge.svg?branch=main)](https://github.com/kobotoolbox/kpi/actions?query=workflow%3Apytest+branch%3Amain)
[![Python Build Status](https://github.com/kobotoolbox/kpi/actions/workflows/pytest.yml/badge.svg?branch=main)](https://github.com/kobotoolbox/kpi/actions?query=workflow%3Apytest+branch%3Amain)
[![Python Coverage Status](https://coveralls.io/repos/github/kobotoolbox/kpi/badge.svg?branch=main)](https://coveralls.io/github/kobotoolbox/kpi?branch=main)
[![JavaScript Build Status](https://github.com/kobotoolbox/kpi/workflows/npm-test/badge.svg?branch=main)](https://github.com/kobotoolbox/kpi/actions?query=workflow%3Anpm-test+branch%3Amain)
[![JavaScript Build Status](https://github.com/kobotoolbox/kpi/actions/workflows/npm-test.yml/badge.svg?branch=main)](https://github.com/kobotoolbox/kpi/actions?query=workflow%3Anpm-test+branch%3Amain)

For production always use a specific release branch, `main` branch may include breaking changes. Run `git branch -rl 'origin/release/*'` to list release branches and then switch to a release branch of your choice.

Expand Down
4 changes: 2 additions & 2 deletions dependencies/pip/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ oauthlib==3.2.2
# -r dependencies/pip/requirements.in
# django-oauth-toolkit
# requests-oauthlib
openpyxl==3.0.9
openpyxl==3.1.3
# via
# -r dependencies/pip/requirements.in
# pyxform
Expand Down Expand Up @@ -537,7 +537,7 @@ pytz==2024.1
# via
# flower
# pandas
pyxform==1.9.0
pyxform==2.2.0
# via
# -r dependencies/pip/requirements.in
# formpack
Expand Down
2 changes: 1 addition & 1 deletion dependencies/pip/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ openpyxl
psycopg
pymongo
python-dateutil
pyxform==1.9.0
pyxform==2.2.0
requests
regex
responses
Expand Down
4 changes: 2 additions & 2 deletions dependencies/pip/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ oauthlib==3.2.2
# -r dependencies/pip/requirements.in
# django-oauth-toolkit
# requests-oauthlib
openpyxl==3.0.9
openpyxl==3.1.3
# via
# -r dependencies/pip/requirements.in
# pyxform
Expand Down Expand Up @@ -412,7 +412,7 @@ pytz==2024.1
# via
# flower
# pandas
pyxform==1.9.0
pyxform==2.2.0
# via
# -r dependencies/pip/requirements.in
# formpack
Expand Down
43 changes: 41 additions & 2 deletions hub/admin/extend_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from kobo.apps.trash_bin.models.account import AccountTrash
from kobo.apps.trash_bin.utils import move_to_trash
from kpi.models.asset import AssetDeploymentStatus

from .filters import UserAdvancedSearchFilter
from .mixins import AdvancedSearchMixin

Expand Down Expand Up @@ -87,8 +88,10 @@ class OrgInline(admin.StackedInline):
'organization',
'is_admin',
]
can_delete = False
# Override H2 style to make inline section like other fieldsets
classes = ('no-upper',)
raw_id_fields = ('user', 'organization')
readonly_fields = settings.STRIPE_ENABLED and ('active_subscription_status',) or []

def active_subscription_status(self, obj):
if settings.STRIPE_ENABLED:
Expand All @@ -98,6 +101,12 @@ def active_subscription_status(self, obj):
else 'None'
)

def get_readonly_fields(self, request, obj=None):
readonly_fields = ['organization', 'is_admin']
if settings.STRIPE_ENABLED:
readonly_fields.append('active_subscription_status')
return readonly_fields

def has_add_permission(self, request, obj=OrganizationUser):
return False

Expand Down Expand Up @@ -158,6 +167,9 @@ class ExtendedUserAdmin(AdvancedSearchMixin, UserAdmin):
)
actions = ['remove', 'delete']

class Media:
css = {'all': ('admin/css/inline_as_fieldset.css',)}

@admin.action(description='Remove selected users (delete everything but their username)')
def remove(self, request, queryset, **kwargs):
"""
Expand Down Expand Up @@ -235,8 +247,9 @@ def get_queryset(self, request):
)

def get_search_results(self, request, queryset, search_term):

if request.path != '/admin/auth/user/':
queryset = self._filter_queryset(request, queryset)

# If search comes from autocomplete field, use parent class method
return super(UserAdmin, self).get_search_results(
request, queryset, search_term
Expand All @@ -261,6 +274,32 @@ def monthly_submission_count(self, obj):
).aggregate(counter=Sum('counter'))
return instances.get('counter')

def _filter_queryset(self, request, queryset):
auto_complete = request.path == '/admin/autocomplete/'
app_label = request.GET.get('app_label')
model_name = request.GET.get('model_name')

if (
auto_complete
and app_label == 'organizations'
and model_name == 'organizationuser'
):
return self._filter_queryset_for_organization_user(queryset)

return queryset

def _filter_queryset_for_organization_user(self, queryset):
"""
Displays only users whose organization has a single member.
"""
return (
queryset.annotate(
user_count=Count('organizations_organization__organization_users')
)
.filter(user_count__lte=1)
.order_by('username')
)

def _remove_or_delete(
self,
request,
Expand Down
5 changes: 3 additions & 2 deletions hub/models/extra_user_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,6 @@ def _sync_org_name(self):
except (KeyError, AttributeError):
organization_name = None

user_organization.name = organization_name
user_organization.save(update_fields=['name'])
if organization_name:
user_organization.name = organization_name
user_organization.save(update_fields=['name'])
3 changes: 3 additions & 0 deletions hub/static/admin/css/inline_as_fieldset.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.no-upper h2 {
text-transform: unset;
}
18 changes: 6 additions & 12 deletions jsapp/js/account/accountSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ function AccountSidebar() {
setShowPlans(true);
}, [subscriptionStore.isInitialised]);

const showAddOnsLink = useMemo(() => {
return !subscriptionStore.planResponse.length;
}, [subscriptionStore.isInitialised]);

return (
<nav className={styles.accountSidebar}>
<AccountNavLink
Expand All @@ -78,14 +74,12 @@ function AccountSidebar() {
name={t('Plans')}
to={ACCOUNT_ROUTES.PLAN}
/>
{showAddOnsLink && (
<AccountNavLink
iconName='plus'
name={t('Add-ons')}
to={ACCOUNT_ROUTES.ADD_ONS}
isNew
/>
)}
<AccountNavLink
iconName='plus'
name={t('Add-ons')}
to={ACCOUNT_ROUTES.ADD_ONS}
isNew
/>
</>
)}
</>
Expand Down
Loading