mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 23:16:15 +08:00
Merge pull request #900 from ZmagoD/zd_SCI_1854
adds premissions service to FE
This commit is contained in:
commit
ebd354e4d5
63
app/controllers/client_api/permissions_controller.rb
Normal file
63
app/controllers/client_api/permissions_controller.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
module ClientApi
|
||||
class PermissionsController < ApplicationController
|
||||
before_action :generate_permissions_object, only: :status
|
||||
|
||||
def status
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @permissions, status: :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_permissions_object
|
||||
sanitize_permissions!
|
||||
@permissions = {}
|
||||
obj = @resource.fetch(:type)
|
||||
.constantize
|
||||
.public_send(:find_by_id, @resource.fetch(:id) {
|
||||
raise ArgumentError, 'ID must be present'
|
||||
}) if @resource
|
||||
@required_permissions.each do |permission|
|
||||
trim_permission = permission.gsub('can_', '')
|
||||
if @resource
|
||||
# return false if object does not exist
|
||||
result = obj ? @holder.eval(trim_permission, current_user, obj) : false
|
||||
@permissions.merge!(permission => result)
|
||||
else
|
||||
@permissions.merge!(
|
||||
permission => @holder.eval_generic(
|
||||
trim_permission, current_user
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_permissions!
|
||||
@required_permissions = params.fetch(:requiredPermissions) do
|
||||
:permissions_array_missing
|
||||
end
|
||||
@holder = Canaid::PermissionsHolder.instance
|
||||
@required_permissions.each do |permission|
|
||||
next if @holder.has_permission?(permission.gsub('can_', ''))
|
||||
# this error should happen only in development
|
||||
raise ArgumentError, "Method #{permission} has no related " \
|
||||
"permission registered."
|
||||
end
|
||||
# sanitize resource, this error should happen only in development
|
||||
raise ArgumentError,
|
||||
"Resource #{@resource} does not exists" unless resource_valid?
|
||||
end
|
||||
|
||||
def resource_valid?
|
||||
@resource = params[:resource]
|
||||
return true unless @resource
|
||||
return true if Object.const_get(@resource.fetch(:type).classify)
|
||||
rescue NameError
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -103,4 +103,4 @@ MyProfile.propTypes = {
|
|||
addCurrentUser: func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { addCurrentUser })(MyProfile);
|
||||
export default connect(null, { addCurrentUser })(MyProfile)
|
||||
|
|
|
@ -5,10 +5,18 @@ import styled from "styled-components";
|
|||
import { FormattedMessage, FormattedPlural } from "react-intl";
|
||||
import { Button, Glyphicon } from "react-bootstrap";
|
||||
import { SETTINGS_NEW_TEAM_ROUTE } from "../../../../../config/routes";
|
||||
import * as Permissions from "../../../../../services/permissions"
|
||||
|
||||
const Wrapper = styled.div`margin: 15px 0;`;
|
||||
const TeamsPageDetails = ({ teams }) => {
|
||||
const TeamsPageDetails = ({ teams, permissions }) => {
|
||||
const teamsNumber = teams.length;
|
||||
const newTeamButton = (
|
||||
<LinkContainer to={SETTINGS_NEW_TEAM_ROUTE}>
|
||||
<Button>
|
||||
<Glyphicon glyph="plus" /> <FormattedMessage id="global_team_switch.new_team" />
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
)
|
||||
return (
|
||||
<Wrapper>
|
||||
<FormattedPlural
|
||||
|
@ -30,11 +38,7 @@ const TeamsPageDetails = ({ teams }) => {
|
|||
/>
|
||||
}
|
||||
/>
|
||||
<LinkContainer to={SETTINGS_NEW_TEAM_ROUTE}>
|
||||
<Button>
|
||||
<Glyphicon glyph="plus" /> <FormattedMessage id="global_team_switch.new_team" />
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
{permissions.can_create_teams ? newTeamButton : ''}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
@ -53,7 +57,8 @@ TeamsPageDetails.propTypes = {
|
|||
};
|
||||
|
||||
TeamsPageDetails.defaultProps = {
|
||||
teams: []
|
||||
teams: [],
|
||||
permissions: {}
|
||||
};
|
||||
|
||||
export default TeamsPageDetails;
|
||||
export default Permissions.connect(TeamsPageDetails, ["can_create_teams"]);
|
||||
|
|
|
@ -40,3 +40,6 @@ export const SETTINGS_TEAMS = "/settings/teams";
|
|||
|
||||
// scinote configurations
|
||||
export const ABOUT_SCINOTE_PATH = "/client_api/about_scinote";
|
||||
|
||||
// permissions
|
||||
export const PERMISSIONS_PATH = "/client_api/premissions";
|
||||
|
|
16
app/javascript/src/services/api/permissions_api.js
Normal file
16
app/javascript/src/services/api/permissions_api.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// @flow
|
||||
|
||||
import axiosInstance from "./config";
|
||||
import { PERMISSIONS_PATH } from "./endpoints";
|
||||
|
||||
export const getPermissionStatus = (
|
||||
requiredPermissions: Array<string>,
|
||||
resource: string
|
||||
): Promise<*> => {
|
||||
return axiosInstance
|
||||
.post(PERMISSIONS_PATH, {
|
||||
requiredPermissions,
|
||||
resource
|
||||
})
|
||||
.then(({ data }) => data);
|
||||
};
|
135
app/javascript/src/services/permissions/index.js
Normal file
135
app/javascript/src/services/permissions/index.js
Normal file
|
@ -0,0 +1,135 @@
|
|||
// @flow
|
||||
/*
|
||||
To use this HOC you need to import in you targeted component:
|
||||
|
||||
> import * as Permissions from "relative path../services/permissions"
|
||||
|
||||
Than you use the Permissions.connect method to wrap your component and
|
||||
pass this "permissions helper methods" in your component params:
|
||||
|
||||
If you need to specific model you have to specify it in the connect method
|
||||
like the example below:
|
||||
>
|
||||
> Permissions.connect(MyComponent, ["can_update_team", "can_read_team"], "Team");
|
||||
>
|
||||
|
||||
In case your component is connected to Redux or some other HOC you can simply
|
||||
chain the HOC's:
|
||||
>
|
||||
> const mapStateToProps = ({ current_team }) => ({ current_team });
|
||||
> const MyComponentWithPermissions = Permissions.connect(MyComponent, ["can_read_team"], "Team");
|
||||
> export default connect(mapStateToProps)(MyComponentWithPermissions);
|
||||
>
|
||||
Beside the permissions object there's also the setPermissionResourceId/1 function in your component props.
|
||||
This function should be used to pass the ID of the resource when you have it.
|
||||
|
||||
Example: you need the current team for whatever reason you can call it in the
|
||||
shouldComponentUpdate function...
|
||||
|
||||
> shouldComponentUpdate(nextProps: any, nextState: any) {
|
||||
> this.props.setPermissionResourceId(this.props.current_team.id);
|
||||
> return true; // remember to return true!
|
||||
> }
|
||||
|
||||
JUST REMEMBER THAT YOU HAVE TO PASS A VALID ID and you have to check if it's present at the moment of the execution.
|
||||
THE REQUEST WILL BE TRIGGERED WHEN YOU INVOKE setPermissionResourceId/1 FUNCTION!!!
|
||||
|
||||
Otherwise (generic permissions without the accessed object) you can just pass the permissions on the user
|
||||
>
|
||||
> Permissions.connect(MyComponent, ["can_update"])
|
||||
>
|
||||
THE REQUEST WILL BE TRIGGERED WHEN THE COMPONENT MOUNTS!!!
|
||||
|
||||
Now you can access your permissions through component params. The permissions
|
||||
you required have 3 states [true, false, null]. Null is when you are waiting for server response.
|
||||
|
||||
Finally you can access your permissions in the component using props.permissions.can_... whatever you specify.
|
||||
The props.permissions is basically an object that holds all required permissions.
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import { getPermissionStatus } from "../api/permissions_api";
|
||||
|
||||
type State = {
|
||||
permissions: any
|
||||
};
|
||||
|
||||
type ResourceObject = {
|
||||
type: string,
|
||||
id: number
|
||||
};
|
||||
|
||||
type PermissionsObject = {
|
||||
[string]: boolean | null
|
||||
};
|
||||
/*
|
||||
This function accepts 3 arguments which are REQUIRED
|
||||
1.) @WrappedComponent: Component that you want to have permissions
|
||||
2.) @requiredPermissions: an array of strings with permissions methods that
|
||||
will be available in your component
|
||||
3.) @resource: a string of reference/model name
|
||||
*/
|
||||
export function connect<Props: {}>(
|
||||
WrappedComponent: React.ComponentType<Props>,
|
||||
requiredPermissions: Array<string> = [],
|
||||
resource: string
|
||||
) {
|
||||
const parsedPermissions: PermissionsObject = {};
|
||||
requiredPermissions.forEach(el => {
|
||||
parsedPermissions[el] = null;
|
||||
});
|
||||
return class extends React.Component<*, State> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
permissions: parsedPermissions,
|
||||
permissionsRequestDone: false
|
||||
};
|
||||
(this: any).getPermissions = this.getPermissions.bind(this);
|
||||
(this: any).setPermissionResourceId = this.setPermissionResourceId.bind(
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
if (!resource) {
|
||||
this.getPermissions(requiredPermissions, resource);
|
||||
}
|
||||
}
|
||||
|
||||
setPermissionResourceId(id: number): void {
|
||||
this.getPermissions(requiredPermissions, { type: resource, id });
|
||||
}
|
||||
|
||||
getPermissions(
|
||||
permissionsArray: Array<string>,
|
||||
resourceObject: ResourceObject | undefined
|
||||
): void {
|
||||
if (!this.state.permissionsRequestDone) {
|
||||
getPermissionStatus(permissionsArray, resourceObject)
|
||||
.then(data => {
|
||||
this.setState({ permissions: data, permissionsRequestDone: true });
|
||||
})
|
||||
.catch(() => {
|
||||
const permissions: PermissionsObject = {};
|
||||
permissionsArray.forEach(el => {
|
||||
permissions[el] = false;
|
||||
});
|
||||
this.setState({ permissions });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render(): any {
|
||||
return (
|
||||
<WrappedComponent
|
||||
permissions={this.state.permissions}
|
||||
setPermissionResourceId={
|
||||
resource ? this.setPermissionResourceId : undefined
|
||||
}
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -18,6 +18,7 @@ Rails.application.routes.draw do
|
|||
get '/settings/*all', to: 'client_api/settings#index'
|
||||
|
||||
namespace :client_api, defaults: { format: 'json' } do
|
||||
post '/premissions', to: 'permissions#status'
|
||||
%i(activities teams notifications users configurations).each do |path|
|
||||
draw path
|
||||
end
|
||||
|
|
340
flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js
vendored
Normal file
340
flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,340 @@
|
|||
// flow-typed signature: 2a83afa8301f1298c0c192309eab48de
|
||||
// flow-typed version: <<STUB>>/eslint-plugin-flowtype_v^2.39.1/flow_v0.56.0
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'eslint-plugin-flowtype'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'eslint-plugin-flowtype' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'eslint-plugin-flowtype/bin/readmeAssertions' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noMutableArray' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/semi' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/sortKeys' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/useFlowType' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/validSyntax' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/quoteName' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'eslint-plugin-flowtype/bin/readmeAssertions.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/bin/readmeAssertions'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/index.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/index'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/booleanStyle'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/defineFlowType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/delimiterDangle'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/genericSpacing'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noDupeKeys'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noMutableArray.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noMutableArray'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noUnusedExpressions'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noWeakTypes'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireParameterType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireReturnType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireVariableType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/semi.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/semi'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/sortKeys.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/sortKeys'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeIdMatch'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/useFlowType.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/useFlowType'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/rules/validSyntax.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/validSyntax'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getParameterName'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/index.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/index'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFile'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/quoteName.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/quoteName'>;
|
||||
}
|
||||
declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers.js' {
|
||||
declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/spacingFixers'>;
|
||||
}
|
2
flow-typed/npm/lodash_v4.x.x.js
vendored
2
flow-typed/npm/lodash_v4.x.x.js
vendored
|
@ -4204,4 +4204,4 @@ declare module "lodash/toPath" {
|
|||
|
||||
declare module "lodash/uniqueId" {
|
||||
declare module.exports: $PropertyType<$Exports<"lodash">, "uniqueId">;
|
||||
}
|
||||
}
|
||||
|
|
58
flow-typed/npm/redux_v3.x.x.js
vendored
58
flow-typed/npm/redux_v3.x.x.js
vendored
|
@ -1,5 +1,5 @@
|
|||
// flow-typed signature: 33b83b6284653250e74578cf4dbe6124
|
||||
// flow-typed version: e282e4128f/redux_v3.x.x/flow_>=v0.33.x
|
||||
// flow-typed signature: ec7daead5cb4fec5ab25fedbedef29e8
|
||||
// flow-typed version: 2c04631d20/redux_v3.x.x/flow_>=v0.55.x
|
||||
|
||||
declare module 'redux' {
|
||||
|
||||
|
@ -55,55 +55,5 @@ declare module 'redux' {
|
|||
|
||||
declare export function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;
|
||||
|
||||
declare export function compose<A, B>(ab: (a: A) => B): (a: A) => B
|
||||
declare export function compose<A, B, C>(
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => C
|
||||
declare export function compose<A, B, C, D>(
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => D
|
||||
declare export function compose<A, B, C, D, E>(
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => E
|
||||
declare export function compose<A, B, C, D, E, F>(
|
||||
ef: (e: E) => F,
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => F
|
||||
declare export function compose<A, B, C, D, E, F, G>(
|
||||
fg: (f: F) => G,
|
||||
ef: (e: E) => F,
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => G
|
||||
declare export function compose<A, B, C, D, E, F, G, H>(
|
||||
gh: (g: G) => H,
|
||||
fg: (f: F) => G,
|
||||
ef: (e: E) => F,
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => H
|
||||
declare export function compose<A, B, C, D, E, F, G, H, I>(
|
||||
hi: (h: H) => I,
|
||||
gh: (g: G) => H,
|
||||
fg: (f: F) => G,
|
||||
ef: (e: E) => F,
|
||||
de: (d: D) => E,
|
||||
cd: (c: C) => D,
|
||||
bc: (b: B) => C,
|
||||
ab: (a: A) => B
|
||||
): (a: A) => I
|
||||
|
||||
}
|
||||
declare export var compose: $Compose;
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
"eslint-config-airbnb": "^15.1.0",
|
||||
"eslint-config-google": "^0.9.1",
|
||||
"eslint-config-prettier": "^2.3.0",
|
||||
"eslint-plugin-flowtype": "^2.39.1",
|
||||
"eslint-plugin-import": "^2.7.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.0.2",
|
||||
"eslint-plugin-prettier": "^2.1.2",
|
||||
|
|
73
spec/controllers/client_api/permissions_controller_spec.rb
Normal file
73
spec/controllers/client_api/permissions_controller_spec.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe ClientApi::PermissionsController, type: :controller do
|
||||
login_user
|
||||
|
||||
describe '#status' do
|
||||
let!(:user) { User.first || create(:user) }
|
||||
let!(:team) { create :team, created_by: user }
|
||||
let!(:user_team) { create :user_team, user: user, team: team, role: 2 }
|
||||
let(:params) do
|
||||
{ requiredPermissions: ['can_read_team'],
|
||||
resource: { type: 'Team', id: team.id } }
|
||||
end
|
||||
|
||||
let(:subject) { post :status, format: :json, params: params }
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it 'returns an object with the permission' do
|
||||
body = JSON.parse(subject.body)
|
||||
expect(body).to eq('can_read_team' => true)
|
||||
end
|
||||
|
||||
it 'raises an error if no required permissions passed' do
|
||||
expect do
|
||||
post :status,
|
||||
format: :json,
|
||||
params: { resource: { type: 'Team', id: team.id } }
|
||||
end
|
||||
.to raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'raises an error if no required resource type invalid' do
|
||||
expect do
|
||||
post :status,
|
||||
format: :json,
|
||||
params: { requiredPermissions: ['can_read_team'],
|
||||
resource: { type: 'Banana', id: team.id } }
|
||||
end
|
||||
.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'raises an error if no required resource id is not present' do
|
||||
expect do
|
||||
post :status,
|
||||
format: :json,
|
||||
params: { requiredPermissions: ['can_read_team'],
|
||||
resource: { type: 'Team' } }
|
||||
end
|
||||
.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
context 'raises an error if can\'t find permission invalid when resource' do
|
||||
it 'is absent' do
|
||||
expect do
|
||||
post :status,
|
||||
format: :json,
|
||||
params: { requiredPermissions: ['can_throw_bananas'] }
|
||||
end
|
||||
.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'is present' do
|
||||
expect do
|
||||
post :status,
|
||||
format: :json,
|
||||
params: { requiredPermissions: ['can_throw_bananas'],
|
||||
resource: { type: 'Team', id: team.id } }
|
||||
end
|
||||
.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2119,6 +2119,12 @@ eslint-module-utils@^2.1.1:
|
|||
debug "^2.6.8"
|
||||
pkg-dir "^1.0.0"
|
||||
|
||||
eslint-plugin-flowtype@^2.39.1:
|
||||
version "2.39.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.39.1.tgz#b5624622a0388bcd969f4351131232dcb9649cd5"
|
||||
dependencies:
|
||||
lodash "^4.15.0"
|
||||
|
||||
eslint-plugin-import@^2.7.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f"
|
||||
|
@ -3711,7 +3717,7 @@ lodash.uniq@^4.5.0:
|
|||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
|
||||
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4:
|
||||
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
|
|
Loading…
Reference in a new issue