diff --git a/cmd/zrok/adminCreateOrgMember.go b/cmd/zrok/adminCreateOrgMember.go new file mode 100644 index 00000000..fc15e3a1 --- /dev/null +++ b/cmd/zrok/adminCreateOrgMember.go @@ -0,0 +1,54 @@ +package main + +import ( + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/rest_client_zrok/admin" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func init() { + adminCreateCmd.AddCommand(newAdminCreateOrgMemberCommand().cmd) +} + +type adminCreateOrgMemberCommand struct { + cmd *cobra.Command + admin bool +} + +func newAdminCreateOrgMemberCommand() *adminCreateOrgMemberCommand { + cmd := &cobra.Command{ + Use: "org-member ", + Aliases: []string{"member"}, + Short: "Add an account to an organization", + Args: cobra.ExactArgs(2), + } + command := &adminCreateOrgMemberCommand{cmd: cmd} + cmd.Flags().BoolVar(&command.admin, "admin", false, "Make the new account an admin of the organization") + cmd.Run = command.run + return command +} + +func (cmd *adminCreateOrgMemberCommand) run(_ *cobra.Command, args []string) { + env, err := environment.LoadRoot() + if err != nil { + panic(err) + } + + zrok, err := env.Client() + if err != nil { + panic(err) + } + + req := admin.NewAddOrganizationMemberParams() + req.Body.Email = args[0] + req.Body.Token = args[1] + req.Body.Admin = cmd.admin + + _, err = zrok.Admin.AddOrganizationMember(req, mustGetAdminAuth()) + if err != nil { + panic(err) + } + + logrus.Infof("added '%v' to organization '%v", args[0], args[1]) +} diff --git a/controller/addOrganizationMember.go b/controller/addOrganizationMember.go index 417c6117..b9c7e1db 100644 --- a/controller/addOrganizationMember.go +++ b/controller/addOrganizationMember.go @@ -38,7 +38,7 @@ func (h *addOrganizationMemberHandler) Handle(params admin.AddOrganizationMember return admin.NewAddOrganizationMemberNotFound() } - if err := str.AddAccountToOrganization(acct.Id, org.Id, trx); err != nil { + if err := str.AddAccountToOrganization(acct.Id, org.Id, params.Body.Admin, trx); err != nil { logrus.Errorf("error adding account '%v' to organization '%v': %v", acct.Email, org.Token, err) return admin.NewAddOrganizationMemberInternalServerError() } diff --git a/controller/store/organizationMember.go b/controller/store/organizationMember.go index ec9f1108..eba3e96f 100644 --- a/controller/store/organizationMember.go +++ b/controller/store/organizationMember.go @@ -5,12 +5,12 @@ import ( "github.com/pkg/errors" ) -func (str *Store) AddAccountToOrganization(acctId, orgId int, trx *sqlx.Tx) error { - stmt, err := trx.Prepare("insert into organization_members (organization_id, account_id) values ($1, $2)") +func (str *Store) AddAccountToOrganization(acctId, orgId int, admin bool, trx *sqlx.Tx) error { + stmt, err := trx.Prepare("insert into organization_members (account_id, organization_id, admin) values ($1, $2, $3)") if err != nil { return errors.Wrap(err, "error preparing organization_members insert statement") } - _, err = stmt.Exec(acctId, orgId) + _, err = stmt.Exec(acctId, orgId, admin) if err != nil { return errors.Wrap(err, "error executing organization_members insert statement") } diff --git a/rest_client_zrok/admin/add_organization_member_responses.go b/rest_client_zrok/admin/add_organization_member_responses.go index 29c3f8be..60866458 100644 --- a/rest_client_zrok/admin/add_organization_member_responses.go +++ b/rest_client_zrok/admin/add_organization_member_responses.go @@ -281,6 +281,9 @@ swagger:model AddOrganizationMemberBody */ type AddOrganizationMemberBody struct { + // admin + Admin bool `json:"admin,omitempty"` + // email Email string `json:"email,omitempty"` diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 4e516895..02875bdf 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -930,6 +930,9 @@ func init() { "in": "body", "schema": { "properties": { + "admin": { + "type": "boolean" + }, "email": { "type": "string" }, @@ -3002,6 +3005,9 @@ func init() { "in": "body", "schema": { "properties": { + "admin": { + "type": "boolean" + }, "email": { "type": "string" }, diff --git a/rest_server_zrok/operations/admin/add_organization_member.go b/rest_server_zrok/operations/admin/add_organization_member.go index 12a69aa2..ce8f8db5 100644 --- a/rest_server_zrok/operations/admin/add_organization_member.go +++ b/rest_server_zrok/operations/admin/add_organization_member.go @@ -78,6 +78,9 @@ func (o *AddOrganizationMember) ServeHTTP(rw http.ResponseWriter, r *http.Reques // swagger:model AddOrganizationMemberBody type AddOrganizationMemberBody struct { + // admin + Admin bool `json:"admin,omitempty"` + // email Email string `json:"email,omitempty"` diff --git a/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/FILES b/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/FILES index b1dd39f5..702edf4c 100644 --- a/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/FILES +++ b/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/FILES @@ -41,6 +41,7 @@ model/regenerateToken200Response.ts model/regenerateTokenRequest.ts model/registerRequest.ts model/registerResponse.ts +model/removeOrganizationMemberRequest.ts model/resetPasswordRequest.ts model/share.ts model/shareRequest.ts diff --git a/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts index 289442b0..084b3d2b 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts @@ -28,6 +28,7 @@ import { InviteTokenGenerateRequest } from '../model/inviteTokenGenerateRequest' import { ListOrganizationMembers200Response } from '../model/listOrganizationMembers200Response'; import { PublicFrontend } from '../model/publicFrontend'; import { RegenerateToken200Response } from '../model/regenerateToken200Response'; +import { RemoveOrganizationMemberRequest } from '../model/removeOrganizationMemberRequest'; import { UpdateFrontendRequest } from '../model/updateFrontendRequest'; import { ObjectSerializer, Authentication, VoidAuth, Interceptor } from '../model/models'; @@ -790,7 +791,7 @@ export class AdminApi { * * @param body */ - public async removeOrganizationMember (body?: AddOrganizationMemberRequest, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body?: any; }> { + public async removeOrganizationMember (body?: RemoveOrganizationMemberRequest, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body?: any; }> { const localVarPath = this.basePath + '/organization/remove'; let localVarQueryParameters: any = {}; let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); @@ -807,7 +808,7 @@ export class AdminApi { uri: localVarPath, useQuerystring: this._useQuerystring, json: true, - body: ObjectSerializer.serialize(body, "AddOrganizationMemberRequest") + body: ObjectSerializer.serialize(body, "RemoveOrganizationMemberRequest") }; let authenticationPromise = Promise.resolve(); diff --git a/sdk/nodejs/sdk/src/zrok/api/model/addOrganizationMemberRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/addOrganizationMemberRequest.ts index a2a677fa..9b918462 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/addOrganizationMemberRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/addOrganizationMemberRequest.ts @@ -15,6 +15,7 @@ import { RequestFile } from './models'; export class AddOrganizationMemberRequest { 'token'?: string; 'email'?: string; + 'admin'?: boolean; static discriminator: string | undefined = undefined; @@ -28,6 +29,11 @@ export class AddOrganizationMemberRequest { "name": "email", "baseName": "email", "type": "string" + }, + { + "name": "admin", + "baseName": "admin", + "type": "boolean" } ]; static getAttributeTypeMap() { diff --git a/sdk/nodejs/sdk/src/zrok/api/model/models.ts b/sdk/nodejs/sdk/src/zrok/api/model/models.ts index 7aa8fb8a..77765e42 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/models.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/models.ts @@ -34,6 +34,7 @@ export * from './regenerateToken200Response'; export * from './regenerateTokenRequest'; export * from './registerRequest'; export * from './registerResponse'; +export * from './removeOrganizationMemberRequest'; export * from './resetPasswordRequest'; export * from './share'; export * from './shareRequest'; @@ -93,6 +94,7 @@ import { RegenerateToken200Response } from './regenerateToken200Response'; import { RegenerateTokenRequest } from './regenerateTokenRequest'; import { RegisterRequest } from './registerRequest'; import { RegisterResponse } from './registerResponse'; +import { RemoveOrganizationMemberRequest } from './removeOrganizationMemberRequest'; import { ResetPasswordRequest } from './resetPasswordRequest'; import { Share } from './share'; import { ShareRequest } from './shareRequest'; @@ -160,6 +162,7 @@ let typeMap: {[index: string]: any} = { "RegenerateTokenRequest": RegenerateTokenRequest, "RegisterRequest": RegisterRequest, "RegisterResponse": RegisterResponse, + "RemoveOrganizationMemberRequest": RemoveOrganizationMemberRequest, "ResetPasswordRequest": ResetPasswordRequest, "Share": Share, "ShareRequest": ShareRequest, diff --git a/sdk/nodejs/sdk/src/zrok/api/model/removeOrganizationMemberRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/removeOrganizationMemberRequest.ts new file mode 100644 index 00000000..8caf373b --- /dev/null +++ b/sdk/nodejs/sdk/src/zrok/api/model/removeOrganizationMemberRequest.ts @@ -0,0 +1,37 @@ +/** + * zrok + * zrok client access + * + * The version of the OpenAPI document: 0.3.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +export class RemoveOrganizationMemberRequest { + 'token'?: string; + 'email'?: string; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "token", + "baseName": "token", + "type": "string" + }, + { + "name": "email", + "baseName": "email", + "type": "string" + } ]; + + static getAttributeTypeMap() { + return RemoveOrganizationMemberRequest.attributeTypeMap; + } +} + diff --git a/sdk/python/sdk/zrok/zrok_api/models/organization_add_body.py b/sdk/python/sdk/zrok/zrok_api/models/organization_add_body.py index 31e66d04..918758ab 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/organization_add_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/organization_add_body.py @@ -29,23 +29,28 @@ class OrganizationAddBody(object): """ swagger_types = { 'token': 'str', - 'email': 'str' + 'email': 'str', + 'admin': 'bool' } attribute_map = { 'token': 'token', - 'email': 'email' + 'email': 'email', + 'admin': 'admin' } - def __init__(self, token=None, email=None): # noqa: E501 + def __init__(self, token=None, email=None, admin=None): # noqa: E501 """OrganizationAddBody - a model defined in Swagger""" # noqa: E501 self._token = None self._email = None + self._admin = None self.discriminator = None if token is not None: self.token = token if email is not None: self.email = email + if admin is not None: + self.admin = admin @property def token(self): @@ -89,6 +94,27 @@ class OrganizationAddBody(object): self._email = email + @property + def admin(self): + """Gets the admin of this OrganizationAddBody. # noqa: E501 + + + :return: The admin of this OrganizationAddBody. # noqa: E501 + :rtype: bool + """ + return self._admin + + @admin.setter + def admin(self, admin): + """Sets the admin of this OrganizationAddBody. + + + :param admin: The admin of this OrganizationAddBody. # noqa: E501 + :type: bool + """ + + self._admin = admin + def to_dict(self): """Returns the model properties as a dict""" result = {} diff --git a/specs/zrok.yml b/specs/zrok.yml index cc15cd72..2c3eace0 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -446,6 +446,8 @@ paths: type: string email: type: string + admin: + type: boolean responses: 201: description: member added