diff --git a/awx/ui/client/features/users/tokens/tokens.strings.js b/awx/ui/client/features/users/tokens/tokens.strings.js index 27b9450992..b906f3fe10 100644 --- a/awx/ui/client/features/users/tokens/tokens.strings.js +++ b/awx/ui/client/features/users/tokens/tokens.strings.js @@ -28,7 +28,8 @@ function TokensStrings (BaseString) { DELETE_ACTION_LABEL: t.s('DELETE'), SCOPE_PLACEHOLDER: t.s('Select a scope'), SCOPE_READ_LABEL: t.s('Read'), - SCOPE_WRITE_LABEL: t.s('Write') + SCOPE_WRITE_LABEL: t.s('Write'), + APPLICATION_HELP_TEXT: t.s('Leaving this field blank will result in the creation of a Personal Access Token which is not linked to an Application.') }; ns.list = { diff --git a/awx/ui/client/features/users/tokens/users-tokens-add.controller.js b/awx/ui/client/features/users/tokens/users-tokens-add.controller.js index 26ce20e5f2..4ad1fa2d27 100644 --- a/awx/ui/client/features/users/tokens/users-tokens-add.controller.js +++ b/awx/ui/client/features/users/tokens/users-tokens-add.controller.js @@ -1,59 +1,72 @@ function AddTokensController ( - models, $state, strings, Rest, Alert, Wait, GetBasePath, + models, $state, strings, Alert, Wait, $filter, ProcessErrors, $scope ) { const vm = this || {}; - const { application } = models; + const { application, token, user } = models; vm.mode = 'add'; vm.strings = strings; vm.panelTitle = strings.get('add.PANEL_TITLE'); - vm.form = {}; - - vm.form.application = { - type: 'field', - label: 'Application', - id: 'application' - }; - vm.form.description = { - type: 'String', - label: 'Description', - id: 'description' - }; - - vm.form.application._resource = 'application'; - vm.form.application._route = 'users.edit.tokens.add.application'; - vm.form.application._model = application; - vm.form.application._placeholder = strings.get('add.APP_PLACEHOLDER'); - vm.form.application.required = true; - - vm.form.description.required = false; - - vm.form.scope = { - choices: [ - [null, ''], - ['read', strings.get('add.SCOPE_READ_LABEL')], - ['write', strings.get('add.SCOPE_WRITE_LABEL')] - ], - help_text: strings.get('add.SCOPE_HELP_TEXT'), - id: 'scope', - label: 'Scope', - required: true, - _component: 'at-input-select', - _data: [ - [null, ''], - ['read', strings.get('add.SCOPE_READ_LABEL')], - ['write', strings.get('add.SCOPE_WRITE_LABEL')] - ], - _exp: 'choice[1] for (index, choice) in state._data', - _format: 'selectFromOptions' + vm.form = { + application: { + type: 'field', + label: 'Application', + id: 'application', + required: false, + help_text: strings.get('add.APPLICATION_HELP_TEXT'), + _resource: 'application', + _route: 'users.edit.tokens.add.application', + _model: application, + _placeholder: strings.get('add.APP_PLACEHOLDER') + }, + description: { + type: 'String', + label: 'Description', + id: 'description', + required: false + }, + scope: { + choices: [ + [null, ''], + ['read', strings.get('add.SCOPE_READ_LABEL')], + ['write', strings.get('add.SCOPE_WRITE_LABEL')] + ], + help_text: strings.get('add.SCOPE_HELP_TEXT'), + id: 'scope', + label: 'Scope', + required: true, + _component: 'at-input-select', + _data: [ + [null, ''], + ['read', strings.get('add.SCOPE_READ_LABEL')], + ['write', strings.get('add.SCOPE_WRITE_LABEL')] + ], + _exp: 'choice[1] for (index, choice) in state._data', + _format: 'selectFromOptions' + } }; vm.form.save = payload => { - Rest.setUrl(`${GetBasePath('users')}${$state.params.user_id}/authorized_tokens`); - return Rest.post(payload) + const postToken = _.has(payload, 'application') ? + user.postAuthorizedTokens({ + id: $state.params.user_id, + payload + }) : token.request('post', { data: payload }); + + return postToken .then(({ data }) => { + const refreshHTML = data.refresh_token ? + `
+
+ ${strings.get('add.REFRESH_TOKEN_LABEL')} +
+
+ ${data.refresh_token} +
+
` : ''; + Alert(strings.get('add.TOKEN_MODAL_HEADER'), `
@@ -63,14 +76,7 @@ function AddTokensController ( ${data.token}
-
-
- ${strings.get('add.REFRESH_TOKEN_LABEL')} -
-
- ${data.refresh_token} -
-
+ ${refreshHTML}
${strings.get('add.TOKEN_EXPIRES_LABEL')} @@ -106,10 +112,8 @@ AddTokensController.$inject = [ 'resolvedModels', '$state', 'TokensStrings', - 'Rest', 'Alert', 'Wait', - 'GetBasePath', '$filter', 'ProcessErrors', '$scope' diff --git a/awx/ui/client/features/users/tokens/users-tokens-add.route.js b/awx/ui/client/features/users/tokens/users-tokens-add.route.js index fe9548b79a..43a663433f 100644 --- a/awx/ui/client/features/users/tokens/users-tokens-add.route.js +++ b/awx/ui/client/features/users/tokens/users-tokens-add.route.js @@ -3,17 +3,21 @@ import AddController from './users-tokens-add.controller'; const addTemplate = require('~features/users/tokens/users-tokens-add.partial.html'); -function TokensDetailResolve ($q, Application) { +function TokensDetailResolve ($q, Application, Token, User) { const promises = {}; promises.application = new Application('options'); + promises.token = new Token('options'); + promises.user = new User('options'); return $q.all(promises); } TokensDetailResolve.$inject = [ '$q', - 'ApplicationModel' + 'ApplicationModel', + 'TokenModel', + 'UserModel' ]; function isMeResolve ($rootScope, $stateParams, $state) { diff --git a/awx/ui/client/lib/models/Token.js b/awx/ui/client/lib/models/Token.js new file mode 100644 index 0000000000..c4dfaf1937 --- /dev/null +++ b/awx/ui/client/lib/models/Token.js @@ -0,0 +1,26 @@ +let Base; + +function setDependentResources () { + this.dependentResources = []; +} + +function TokenModel (method, resource, config) { + Base.call(this, 'tokens'); + + this.Constructor = TokenModel; + this.setDependentResources = setDependentResources.bind(this); + + return this.create(method, resource, config); +} + +function TokenModelLoader (BaseModel) { + Base = BaseModel; + + return TokenModel; +} + +TokenModelLoader.$inject = [ + 'BaseModel', +]; + +export default TokenModelLoader; diff --git a/awx/ui/client/lib/models/User.js b/awx/ui/client/lib/models/User.js new file mode 100644 index 0000000000..da521255cb --- /dev/null +++ b/awx/ui/client/lib/models/User.js @@ -0,0 +1,40 @@ +let Base; +let $http; + +function postAuthorizedTokens (params) { + const req = { + method: 'POST', + url: `${this.path}${params.id}/authorized_tokens/` + }; + + if (params.payload) { + req.data = params.payload; + } + + return $http(req); +} + +function UserModel (method, resource, config) { + Base.call(this, 'users'); + + this.Constructor = UserModel; + this.postAuthorizedTokens = postAuthorizedTokens.bind(this); + + this.model.launch = {}; + + return this.create(method, resource, config); +} + +function UserModelLoader (BaseModel, _$http_) { + Base = BaseModel; + $http = _$http_; + + return UserModel; +} + +UserModelLoader.$inject = [ + 'BaseModel', + '$http' +]; + +export default UserModelLoader; diff --git a/awx/ui/client/lib/models/index.js b/awx/ui/client/lib/models/index.js index d50c825e22..a851d1f29f 100644 --- a/awx/ui/client/lib/models/index.js +++ b/awx/ui/client/lib/models/index.js @@ -22,11 +22,13 @@ import Project from '~models/Project'; import Schedule from '~models/Schedule'; import ProjectUpdate from '~models/ProjectUpdate'; import SystemJob from '~models/SystemJob'; +import Token from '~models/Token'; import UnifiedJobTemplate from '~models/UnifiedJobTemplate'; import WorkflowJob from '~models/WorkflowJob'; import WorkflowJobTemplate from '~models/WorkflowJobTemplate'; import WorkflowJobTemplateNode from '~models/WorkflowJobTemplateNode'; import UnifiedJob from '~models/UnifiedJob'; +import User from '~models/User'; import ModelsStrings from '~models/models.strings'; @@ -59,10 +61,12 @@ angular .service('UnifiedJobModel', UnifiedJob) .service('ProjectUpdateModel', ProjectUpdate) .service('SystemJobModel', SystemJob) + .service('TokenModel', Token) .service('UnifiedJobTemplateModel', UnifiedJobTemplate) .service('WorkflowJobModel', WorkflowJob) .service('WorkflowJobTemplateModel', WorkflowJobTemplate) .service('WorkflowJobTemplateNodeModel', WorkflowJobTemplateNode) + .service('UserModel', User) .service('ModelsStrings', ModelsStrings); export default MODULE_NAME;