Coder Social home page Coder Social logo

cert-polska / mwdb-core Goto Github PK

View Code? Open in Web Editor NEW
305.0 18.0 72.0 13.64 MB

Malware repository component for samples & static configuration with REST API interface.

Home Page: https://mwdb.readthedocs.io/

License: Other

Python 50.86% Shell 0.13% Dockerfile 0.12% JavaScript 0.81% HTML 0.04% CSS 0.53% Mako 0.03% TypeScript 47.48%
repository analysis collection mwdb cert malware-analysis cybersecurity malware-research

mwdb-core's People

Contributors

abudmdbq avatar alex-ilgayev avatar catsuryuu avatar chivay avatar dd8917vk avatar dependabot[bot] avatar disrel avatar dmarxn avatar dskwhitehat avatar itayc0hen avatar j-mie avatar jasperla avatar johnconnorrf avatar jvoisin avatar kwmorale avatar middleware99 avatar msm-cert avatar msm-code avatar nazywam avatar oliwiergawlik avatar postrowinski avatar psrok1 avatar repumba avatar v-rzh avatar vividduck avatar wklimek avatar yankovs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mwdb-core's Issues

Tagging from feed

It would be nice to be able to tag objects directly from feed (Recent objects view). Maybe display [+] while hovering over Tags field.

Moved from CERT.pl internal repository. Reported originally by chivay

typed-config: Use PyPi package after author decide to merge or not (fork or add to requirements)

Typed-config (https://github.com/bwindsor/typed-config) is used by Malwarecage to provide configuration that can be easily extended by plugins.

Current version of library is missing one feature needed for extendability and one bugfix. Both are added/fixed by the following PRs:

I've just copied the fixed code of library under core/typedconfig, but it would be best to use it as PyPi dependency.

Moved from CERT.pl internal repository. Reported originally by psrok1

Query cancellation when Search or Recent objects view is unmounted

  1. Run any long-lasting query on Recent samples tag:mirai AND tag:"feed:urlhaus"
  2. Switch quickly to the Recent configs view
  3. View automatically switches back to the Recent samples.

Promises can't be easily cancelled in current model but at least we should check whether target component is still mounted.

Moved from CERT.pl internal repository. Reported originally by psrok1

[e2e] Frontend tests for object view endpoints

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

  • Lack of e2e frontend tests for:
    • https://<mwdb>/sample/<hash>
    • https://<mwdb>/config/<hash>
    • https://<mwdb>/blob/<hash>

Describe the solution you'd like

Test if view renders correctly in these cases:

  • https://<mwdb>/sample/<existent sha256 hash>
  • https://<mwdb>/sample/<existent md5 hash>
  • https://<mwdb>/sample/<non-existent sha256 hash>
  • https://<mwdb>/sample/<non-existent md5 hash>
  • https://<mwdb>/config/<existent hash>
  • https://<mwdb>/config/<non-existent hash>
  • https://<mwdb>/blob/<existent hash>
  • https://<mwdb>/blob/<non-existent hash>

View and manage installed plugins via the interface

Currently, there is no way to know what plugins are loaded and installed for Malwarecage.
It would be great to have a page in the UI to list the plugins and even a toggle-switch component to turn on or off each plugin.

Unhandled JSONDecodeError results in HTTP 500 error for incorrect JSON data in request

Environment information

  • Malwarecage version (from /about): 2.0.0-alpha1

Behaviour the bug (what happened?)

  • If incorrect JSON is passed to JSON-accepting endpoints - Malwarecage returns HTTP 500 error due to unhandled JSONDecodeError exception.

Expected behaviour

  • Appropriate HTTP 400 response should be returned e.g. JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Proposed fix

  • Recent marshmallow 3.x version is more consistent in terms of validation error reporting: just throws ValidationError instead of returning error via field like obj.errors. We should provide wrapper that loads request data and universally handles both ValidationError, JSONDecodeError and other exceptions that can occur due to corrupted input.

Race condition when the same relation is added simultaneously by different workers

  • Problem probably occurred in model.object.Object.add_parent (test-and-set race)
  • Review model.object.Object.give_access (ObjectPermission.create seems ok at first sight)
  • Need to provide common pattern for these conditions and use it in all places where we're doing inserts with unique-constraint.
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
    cursor.execute(statement, parameters)
psycopg2.IntegrityError: duplicate key value violates unique constraint "ix_relation_parent_child"
DETAIL:  Key (parent_id, child_id)=(3014895, 3014562) already exists.

Moved from CERT.pl internal repository. Reported originally by psrok1

Configurable rate limit for specific group of endpoints

Feature Category

  • Correctness
  • User Interface / User Experience

Describe the problem

  • Currently we don't have any rate limit customization. Rate limiting rules are pretty naive and based on HTTP method:
conn = redis.from_url(app_config.malwarecage.redis_uri)
            if request.method == 'GET':
                """
                DownloadResource is token-based and shouldn't be limited
                """
                if request.endpoint != 'downloadresource':
                    # 1000 per 10 seconds
                    rate_limit(conn, "get-request", 10, 1000)
                    # 2000 per 1 minute
                    rate_limit(conn, "get-request", 60, 2000)
                    # 6000 per 5 minutes
                    rate_limit(conn, "get-request", 5 * 60, 6000)
                    # 10000 per 15 minutes
                    rate_limit(conn, "get-request", 15 * 60, 10000)
            else:
                # 10 per 10 seconds
                rate_limit(conn, "set-request", 10, 10)
                # 30 per 1 minute
                rate_limit(conn, "set-request", 60, 30)
                # 100 per 5 minutes
                rate_limit(conn, "set-request", 5 * 60, 100)
                # 200 per 15 minutes
                rate_limit(conn, "set-request", 15 * 60, 200)

Describe the solution you'd like

We should be able to customize rate limits via configuration with some good defaults included.

Limits should be grouped by their semantics instead of used HTTP method e.g.:

  • list/search objects (request per page)
  • get object information
  • add object information
  • upload/download object
  • general rate limit (?)

Support user-defined queries for easy access

Describe the problem you are facing
Currently, when I want to execute the same set of queries in mwdb frequently (once a day, once a week, ...) I don't have any easy way to do this. Only by typing them ad-hoc or keeping a list of queries at the side.

Describe the solution you'd expect
I would like to have an option to save queries (e.g tag:"yara:win_formbook" AND NOT tag:"ripped:*") so I can quickly access them when I need. In this solution, I could visit the Search page, or a special dashboard, and choose a query I want to execute, without having to type it manually or pasting it from notepad.

Allow to add relation between existing objects from web UI using only hash

Currently the only way to add parent-child relation between files from web UI is to click on Add child button which redirects us to the upload view.
image
In many cases we want to add relation between existing objects by providing identifier (hash) of child object. We should be able to do that without uploading file contents.

Action is already possible from the mwdblib CLI:

$ mwdb link --help
Usage: mwdb link [OPTIONS] PARENT CHILD

  Set relationship for objects

Allow to pass blob contents as 'in-blob' key in uploaded static configuration

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

in-blob key in configuration has special meaning: it allows to put links to blob objects in static configuration that contain the value which is too big to be presented directly or we want to have additional level of relationship on single key level.

image

image

All related blobs must be uploaded manually by user along with proper relationships and config transformation to in-blob form. Malwarecage handles it only at presentation level (web app). It's not very convenient for config uploaders that want to take advantage of this feature.

Describe the solution you'd like

During configuration upload, Malwarecage should look for {"in-blob": ...} structure provided as value:

{
    "config-key": {
        "in-blob": {
           "blob_name": ...
           "blob_type": ...
           "content" ...
        }
}

Blob description should follow the same scheme which is used as blob upload request body:
image

After config upload, the config contents should be transformed to the form before upload:

{
    "config-key": {
        "in-blob": <blob dhash (sha256)>
    }
}

Additional constraints:

  • All related blobs should be uploaded using the same code that is used for single blob upload
  • Malwarecage should add relationship with config as parent and uploaded blob as a child
  • in-blob upload without Capabilities.adding_blobs should result in rejection with HTTP 403 error
  • in-blob value which doesn't follow the TextBlobSchema should result in rejection with HTTP 400 error
  • mwdblib.util.config_dhash utility should handle that case by evaluating sha256 of blob contents and transforming config to "in-blob": <contents sha256> form before the actual hash computing

Bad CSS on Tag elements

Tag appears to have no text, but on hover text changes color.
image

This is caused by all: unset in CSS. To fix I'd propose to remove this hack and properly set CSS on component (color: #fff).

Update react-router package to remove componentWillReceiveProps warning

Change version in package.json to the latest and check whether there is no regression and everything still works.

Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

* Move data fetching code or side effects to componentDidUpdate.
* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

Please update the following components: Switch 
react-dom.development.js:12449

Related issue: remix-run/react-router#6871

Moved from CERT.pl internal repository. Reported originally by psrok1

Allow to use parent/child subqueries in search

Handle parent: and child: selectors in search, accepting FieldGroup with subquery.

Example syntax:

tag:"document:win32:xls" AND parent:(tag:emotet AND upload_time:[2020-01-01 TO 2020-01-04])

which looks for objects tagged as document:win32:xls having parent tagged as emotet and uploaded between 1st and 4th January 2020.

AFAIK that's not the typical use case of Lucene syntax but seems to be correctly handled by Luqum used in Malwarecage.

In [1]: parser.parse("parent:(tag:emotet AND upload_time:[2020-01-01 TO 2020-01-04])")
Out[1]: SearchField('parent', FieldGroup(AndOperation(SearchField('tag', Word('emotet')), SearchField('upload_time', Range(Word('2020-01-01'), Word('2020-01-04'))))))

Redirect to target after successful login trims the query part

Allow users to manage their own groups

Current permission model involves groups that allow users to share samples and all related artifacts within one of their own groups. That's how public feed works - each user is member of "public" group, so everybody can share some objects with all users.

This feature can be used to create groups for organizations that want to have common workspace in Malwarecage. Unfortunately, all group management features and knowledge about group members can be accessed only by Malwarecage administrator (needs manage_users capability) which limits the feature usability for external users.

Proposed improvements:

  • Show list of members of own groups in 'Profile' view, excluding private and public groups
  • Allow to invite other users to own groups using invitation link
  • What with creating new workspaces? Request to admin? We don't have yet any feature that allows to send Action required notification via Malwarecage. Maybe we should optionally allow users to register custom workspaces?
  • What with removing users from workspaces? (e.g. user is no longer employeed in company related with group)

Moved from CERT.pl internal repository. Reported originally by psrok1

Submitting changes to an attribute does not show any indication

Description
As can be seen in the following GIF, when submitting changes to an attribute, the interface shows no indication, even though the entry was indeed updated

Peek 2020-06-10 00-16

Expected behavior

The UI should show an indication to the user that the operation succeeded (or failed).

Backend API code and documentation refactor

There is a huge mess in API documentation, schemas and validation that must be address before the stable release.

Refactored endpoint groups

REST API refactor checklist

  • Schemas:
    • All related schemas should be moved from schema.py to proper schema/.py directory
    • Schemas should have separate Request and Response classes.
    • Inheritance is evil here, don't use it too much.
    • Remember that missing key, null and empty string could have different meaning:
      • missing key is viable for update requests when we don't want to set some attributes or want to use a default
      • null is viable for nullable arguments, non-persisted in database. Can be used in the same meaning as missing key.
      • empty string can be used for persisted fields
  • Don't use obj.data.get(...) for required fields, use obj.data[...] and missing= defaults in Schema
  • Don't call db.session.add(...) for persistent object (objects that are not new, but fetched from database)
  • Whole data validation should be done by Schema's
  • Complex, reusable parts of logic should be moved to model class methods or separate util functions
  • All write actions must be properly logged
  • Don't use authenticated_access, use Object.access directly and raise NotFound if necessary with appropriate message

Post refactor

  • Remove authenticated_access

Event-stream API - subscribable, non-persistent stream with workspace-related events

Endpoint /events which notifies about new objects/tags/elements in mwdb respecting user's workspace view (groups) and permissions.

Feature is limited by fact that we're using synchronous uWSGI backend which doesn't work well with websockets/event-stream.

Implementation proposal by @icedevml:

  • Redis Pub/Sub
  • aiohttp websocket client/server
  • aiohttp websocket server as additional service, subscribe to Redis Pub/Sub, fetch events and pass them to websocket consumers
  • the regular mwdb2 HTTP worker should push events to Redis Pub/Sub so websocket service could fetch them

Moved from CERT.pl internal repository. Reported originally by psrok1

Document how to set up environment variable to point at Karton dashboard

Description

Notice: this PR should be moved to Karton-MWDB Plugin once such repository will be set up

When the Karton-MWDB plugin is installed, in order to get info about the status of tasks, MWDB tries to communicate with Karton dashboard. By default, no such env variable exists.

It would be great to document that such env variable can be set using the mwdb-vars.env

$ cat mwdb-vars.env 
MALWARECAGE_REDIS_URI=redis://redis/
...
...
KARTON_DASHBOARD_URL=http://<KARTON-DASHBOARD-URL>:5000/

URLs containing search query are double-encoded

Direct encodeURIComponent doesn't work because of this bug: remix-run/history#505

We need to:

  • use helper function encodeSearchQuery from @malwarefront/helpers that encodes queries twice
  • bump react-router version and check whether bug is fixed
  • reduce encodeSearchQuery to single encodeURIComponent and check possible regression

Bug is fixed in history 5.0.0 (react-router dependency, remix-run/history#689 , remix-run/history#656)

Fix some long-standing issues, update browser support level, and introduce a few major new features:
...
Stop decoding pathnames (#656)

Unfortunately, v5.0.0 is still beta so we need to use our workaround until stable release.

Reference: remix-run/react-router#7173

Moved from CERT.pl internal repository. Reported originally by psrok1

Customize logging format instead of providing only JSON formatter

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

  • JSON is quite good for machines but not very convenient for humans
  • During tests or development we should be allowed to receive logs in regular format

Describe the solution you'd like

  • Allow to customize log format via Malwarecage configuration (envs and malwarecage.ini) with JSON as a default

Missing maximum password length validation

Behaviour the bug (what happened?)

  • bcrypt silently truncates password to 72 bytes before hashing
  • Malwarecage allows to set longer password than 72 bytes but only the first 72 bytes are considered during authentication

Expected behaviour

  • Return 400 Bad Request when password is too long and will be truncated.
  • Add missing validation in frontend (Set password form) and additional note about the password policy
  • Handle non-encodable passwords (HTTP 400 instead of ISE 500) both in /auth/login and /auth/change_password

Passwords are UTF-8 encoded so limitation must be provided for bytes, not chars.

Reproduction Steps

  • Set password aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaś
  • Password above and aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaź are accepted during logon (the same multibyte prefix for last char)

Additional context

Reported by nsty.

Pre-created group with 'access_all_objects' capability enabled

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

  • Some groups are able to see all objects in Malwarecage (e.g. Malwarecage instance owner).
  • Capability works only for objects uploaded since the option is enabled.
  • After setup: only an admin account has access_all_objects capability enabled. To share all objects with other users in organisation, administrator must create new group with access_all_objects enabled before any object is added or reupload/exclusively share all previously added objects.

Describe the solution you'd like

  • Malwarecage should create group called "everything" with access_all_objects capability enabled
  • Group should be created only on first setup
  • Group should have added "admin" as a member.

General refactor of Relations graph

Related tickets:

  • #12 Relations graph: each update sends requests for all nodes, even those unchanged
  • #20 Relations: graph is looking really bad at higher DPI settings
  • In some parts of code: HTML nodes are created using raw strings instead of JSX + ReactDOM.render

Possible solutions:

  • Use different, ready-made solution for graph generation
  • Use ready-made package for Dagre D3 + React
  • Refactor RelationsPlot component (looks like good use case for React Hooks)

Redirect to target after successful login doesn't work in some cases

On LOGOUT action - navPath is remembered in redux state to be recovered on LOGIN_SUCCESS.

But something goes wrong with that. It works when user log out manually, but expired session is probably triggering this bug, occured when using different browser that wasn't used for a while

Moved from CERT.pl internal repository. Reported originally by chivay

Don't show the Plugins table in About when no plugins available

Feature Category

  • User Interface / User Experience

Describe the problem

When no plugins are installed, an empty table is shown in the about page.

Describe the solution you'd like

Instead of an empty table, write "No plugins are installed. Visit our documentation[link] to learn about Malwarecgae plugins and how they can be used and installed."

Describe alternatives you've considered

Show nothing

Transactional 'tag' adding (like 'metakeys')

Currently we can provide some attributes (known also as "metakeys") along with object contents during upload. They can be used to provide additional information in the same transaction as object upload so they can be used by plugins.

It would be nice to have the same feature available for tags.

Moved from CERT.pl internal repository. Reported originally by psrok1

Broken links on tags

Links are broken on tags.

clicking results with

react-dom.production.min.js:957 Uncaught TypeError: e.props.tagClick is not a function
    at onClick (Tag.js:27)
    at onClick (react-router-dom.js:133)
    at Object.<anonymous> (react-dom.production.min.js:33)
    at h (react-dom.production.min.js:53)
    at react-dom.production.min.js:57
    at m (react-dom.production.min.js:77)
    at at (react-dom.production.min.js:942)
    at it (react-dom.production.min.js:931)
    at st (react-dom.production.min.js:955)
    at pt (react-dom.production.min.js:1041)

Which is caused by:
image

"Hot" samples tab

Allow to query for samples uploaded by multiple groups to provide something like "reputation score" based on number of uploads. This can be used to hunt for interesting campaigns.

Moved from CERT.pl internal repository. Reported originally by nazywam

Provide extended information about plugin

Feature Category

  • Correctness
  • User Experience
  • Performance
  • Other (please explain)

Related issue #36

Describe the problem

Plugins don't identify themselves in Malwarecage. They doesn't inform about the status and plugin version.

Plugin can deliver both backend and frontend extension. Some plugins are frontend-only. Frontend extensions are built into the frontend bundle at compile time. Backend extensions are loaded run-time.

Backend plugin entrypoint (__init__.py) usually looks like this:

from plugin_engine import PluginAppContext

from .resources import MQueryResource
from .schema import MQueryYaraJobSchema


def entrypoint(app_context: PluginAppContext):
    # Initialization code which also could be "first installation" code
    app_context.register_resource(MQueryResource, "/mquery/search")
    app_context.register_schema_spec("MQueryYaraJobSchema", MQueryYaraJobSchema)
    ...

__plugin_entrypoint__ = entrypoint

Describe the solution you'd like

Plugin should provide its author/version/docstring information via module-level dunder names (__author__, __version__ and __doc__ like in __plugin_entrypoint__ case)

"""MQuery integration plugin"""
from plugin_engine import PluginAppContext

from .resources import MQueryResource
from .schema import MQueryYaraJobSchema

__author__ = "CERT Polska"
__version__ = "1.0.0"

def entrypoint(app_context: PluginAppContext):
    # Initialization code which also could be "first installation" code
    app_context.register_resource(MQueryResource, "/mquery/search")
    app_context.register_schema_spec("MQueryYaraJobSchema", MQueryYaraJobSchema)
    ...

__plugin_entrypoint__ = entrypoint

Frontend-only plugins should also deliver the information stub in __init__.py (e.g. plugins/certInfo/__init__.py customizing the logo and adding our Terms of Service)

"""mwdb.cert.pl logo and Terms of Service plugin"""
__author__ = "CERT Polska"
__version__ = "1.0.0"

It means that __init__.py is now mandatory and __plugin_entrypoint__ is optional

These information should be gathered by backend plugin loader plugin_engine.load_plugins https://github.com/CERT-Polska/malwarecage/blob/master/plugin_engine.py#L97 and exposed via global dictionary plugin_engine.loaded_plugins (due to current code structure it would be difficult to expose it other way, good topic for future code refactor)

loaded_plugins = {
	"<module name>": {
		"active": bool
		"author":
		"description":
		"version": ...
	}
}

When __author__, __description__ or __version__ is missing, None should be placed instead.

When plugin is successfully loaded, active should be set to True. False otherwise. The reason of inactivity should stay visible only in logs (the most common case will be probably a lack of configuration).

Complete plugin information (from plugin_engine.loaded_plugins should be exposed via /server endpoint (ServerInfoResource, https://github.com/CERT-Polska/malwarecage/blob/master/resources/server.py#L28)

The plugin information should be exposed in web app's /about view under the banner.

image

Keep in mind that /server is already loaded into the Redux state as "client-side config" (https://github.com/CERT-Polska/malwarecage/blob/master/malwarefront/src/commons/config/config.js) and used to fetch Malwarecage version.

https://github.com/CERT-Polska/malwarecage/blob/20d4b2a25345d22ce10a2b0a336dcf8d43036159/malwarefront/src/components/About.js#L31-L37

Show relationships between config items

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

It is very interesting to see if some of the values in the config are mutual to different samples or even different families. For example, I'd like to click on an IP from QBot's config and see that it reuses an IP from previous Emotet campaigns.

Currently, the only way to see this is when clicking on a config-item it generates a query. The query is too specific (e.g it contains the field name and not only the value, which can cause conflicts with different namings like "C&C" and "remote_server").

Describe the solution you'd like
There are several options. The first one in to visualize the relationships via graph.
Second, is to have a little badge with a number of configs that has the same value and upon click, it will be expanded to graph\search

Document plugin's requirements.txt

Describe the problem

Currently, due to docker limitations (COPY) the existence and the location requirements file of the plugin isn't documented.
For example, for the karton plugin, one need to have a requirements-karton.txt in malwarecage/plugins.

Describe the solution you'd like

Document the requirement for the plugin's requirement file to be in malwarecage/plugins folder and not in the malwarecage/plugins/plugin_name/ folder.

Describe alternatives you've considered

Ignoring caching plugin requirements and building them each time

Filtering by the feed quality

Add the ability to filter by the sample quality. Sample quality may be computed for example as max(uploader.feed_quality) for all the people that uploaded the file.

Moved from CERT.pl internal repository. Reported originally by msm

Don't require clicking on "Update" button to update group permissions

Description

If a user wants to update the permissions of a group, they need to click on the "update" button. This is confusing because the UI shows one state while in reality, without clicking the button, this state is lost.

image

Alternatives:
An alternative approach can be that when the "update" button is grayed out until the changes are made. Then, the button will turn blue and some screen indication will appear to remind the user to save. In addition, if the user left the page with unsaved changes, malwarecage will trigger an "are you sure?" pop-up

Refactor ShowObjectPresenter tabs to avoid raw location rewriting

Currently ShowObjectPresenter.setCurrentTab looks like this:

    setCurrentTab(tab, subtab) {
        let pathElements = this.props.history.location.pathname.split("/");
        let newPath = pathElements.slice(0, 3).concat([tab]).concat(subtab ? [subtab] : []).join("/");
        this.props.history.replace(newPath);
    }

We can use Link component to provide transition between tabs instead of rewriting this.props.history manually.

Moved from CERT.pl internal repository. Reported originally by psrok1

More verbose error message when required capability is missing

Feature Category

  • Correctness
  • User Interface / User Experience
  • Performance
  • Other (please explain)

Describe the problem

If required capability is missing, Malwarecage returns 403 with "You are not permitted to perform this action" without informing which permission is needed.

Describe the solution you'd like

Add more details to the error with name (or friendly name) of required capability.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.