mirror of
https://github.com/openziti/zrok.git
synced 2025-02-08 14:29:52 +01:00
list members of organization (#537)
This commit is contained in:
parent
52333ddb69
commit
917a4d3f22
61
cmd/zrok/adminListOrgMembers.go
Normal file
61
cmd/zrok/adminListOrgMembers.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/jedib0t/go-pretty/v6/table"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/rest_client_zrok/admin"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
adminListCmd.AddCommand(newAdminListOrgMembersCommand().cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type adminListOrgMembersCommand struct {
|
||||||
|
cmd *cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAdminListOrgMembersCommand() *adminListOrgMembersCommand {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "org-members <organizationToken>",
|
||||||
|
Aliases: []string{"members"},
|
||||||
|
Short: "List the members of the specified organization",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
}
|
||||||
|
command := &adminListOrgMembersCommand{cmd: cmd}
|
||||||
|
cmd.Run = command.run
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *adminListOrgMembersCommand) 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.NewListOrganizationMembersParams()
|
||||||
|
req.Body.Token = args[0]
|
||||||
|
|
||||||
|
resp, err := zrok.Admin.ListOrganizationMembers(req, mustGetAdminAuth())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
t := table.NewWriter()
|
||||||
|
t.SetOutputMirror(os.Stdout)
|
||||||
|
t.SetStyle(table.StyleColoredDark)
|
||||||
|
t.AppendHeader(table.Row{"Account Email", "Admin?"})
|
||||||
|
for _, member := range resp.Payload.Members {
|
||||||
|
t.AppendRow(table.Row{member.Email, member.Admin})
|
||||||
|
}
|
||||||
|
t.Render()
|
||||||
|
fmt.Println()
|
||||||
|
}
|
@ -29,22 +29,22 @@ func (h *listOrganizationMembersHandler) Handle(params admin.ListOrganizationMem
|
|||||||
org, err := str.FindOrganizationByToken(params.Body.Token, trx)
|
org, err := str.FindOrganizationByToken(params.Body.Token, trx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error finding organization by token: %v", err)
|
logrus.Errorf("error finding organization by token: %v", err)
|
||||||
return admin.NewListOrganizationMembersInternalServerError()
|
return admin.NewListOrganizationMembersNotFound()
|
||||||
}
|
}
|
||||||
if org == nil {
|
if org == nil {
|
||||||
logrus.Errorf("organization '%v' not found", params.Body.Token)
|
logrus.Errorf("organization '%v' not found", params.Body.Token)
|
||||||
return admin.NewListOrganizationMembersNotFound()
|
return admin.NewListOrganizationMembersNotFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
emails, err := str.FindAccountsForOrganization(org.Id, trx)
|
oms, err := str.FindAccountsForOrganization(org.Id, trx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error finding accounts for organization: %v", err)
|
logrus.Errorf("error finding accounts for organization: %v", err)
|
||||||
return admin.NewListOrganizationMembersInternalServerError()
|
return admin.NewListOrganizationMembersInternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
var members []*admin.ListOrganizationMembersOKBodyMembersItems0
|
var members []*admin.ListOrganizationMembersOKBodyMembersItems0
|
||||||
for _, email := range emails {
|
for _, om := range oms {
|
||||||
members = append(members, &admin.ListOrganizationMembersOKBodyMembersItems0{Email: email})
|
members = append(members, &admin.ListOrganizationMembersOKBodyMembersItems0{Email: om.Email, Admin: om.Admin})
|
||||||
}
|
}
|
||||||
return admin.NewListOrganizationMembersOK().WithPayload(&admin.ListOrganizationMembersOKBody{Members: members})
|
return admin.NewListOrganizationMembersOK().WithPayload(&admin.ListOrganizationMembersOKBody{Members: members})
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,25 @@ func (str *Store) AddAccountToOrganization(acctId, orgId int, admin bool, trx *s
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (str *Store) FindAccountsForOrganization(orgId int, trx *sqlx.Tx) ([]string, error) {
|
type OrganizationMember struct {
|
||||||
return nil, nil
|
Email string
|
||||||
|
Admin bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (str *Store) FindAccountsForOrganization(orgId int, trx *sqlx.Tx) ([]*OrganizationMember, error) {
|
||||||
|
rows, err := trx.Queryx("select organization_members.admin, accounts.email from organization_members, accounts where organization_members.organization_id = $1 and organization_members.account_id = accounts.id", orgId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error querying organization members")
|
||||||
|
}
|
||||||
|
var members []*OrganizationMember
|
||||||
|
for rows.Next() {
|
||||||
|
om := &OrganizationMember{}
|
||||||
|
if err := rows.StructScan(&om); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error scanning account email")
|
||||||
|
}
|
||||||
|
members = append(members, om)
|
||||||
|
}
|
||||||
|
return members, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (str *Store) IsAccountInOrganization(acctId, orgId int, trx *sqlx.Tx) (bool, error) {
|
func (str *Store) IsAccountInOrganization(acctId, orgId int, trx *sqlx.Tx) (bool, error) {
|
||||||
|
@ -441,6 +441,9 @@ swagger:model ListOrganizationMembersOKBodyMembersItems0
|
|||||||
*/
|
*/
|
||||||
type ListOrganizationMembersOKBodyMembersItems0 struct {
|
type ListOrganizationMembersOKBodyMembersItems0 struct {
|
||||||
|
|
||||||
|
// admin
|
||||||
|
Admin bool `json:"admin,omitempty"`
|
||||||
|
|
||||||
// email
|
// email
|
||||||
Email string `json:"email,omitempty"`
|
Email string `json:"email,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -992,6 +992,9 @@ func init() {
|
|||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"admin": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@ -3512,6 +3515,9 @@ func init() {
|
|||||||
"definitions": {
|
"definitions": {
|
||||||
"MembersItems0": {
|
"MembersItems0": {
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"admin": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
@ -223,6 +223,9 @@ func (o *ListOrganizationMembersOKBody) UnmarshalBinary(b []byte) error {
|
|||||||
// swagger:model ListOrganizationMembersOKBodyMembersItems0
|
// swagger:model ListOrganizationMembersOKBodyMembersItems0
|
||||||
type ListOrganizationMembersOKBodyMembersItems0 struct {
|
type ListOrganizationMembersOKBodyMembersItems0 struct {
|
||||||
|
|
||||||
|
// admin
|
||||||
|
Admin bool `json:"admin,omitempty"`
|
||||||
|
|
||||||
// email
|
// email
|
||||||
Email string `json:"email,omitempty"`
|
Email string `json:"email,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ model/grantsRequest.ts
|
|||||||
model/inviteRequest.ts
|
model/inviteRequest.ts
|
||||||
model/inviteTokenGenerateRequest.ts
|
model/inviteTokenGenerateRequest.ts
|
||||||
model/listOrganizationMembers200Response.ts
|
model/listOrganizationMembers200Response.ts
|
||||||
|
model/listOrganizationMembers200ResponseMembersInner.ts
|
||||||
model/loginRequest.ts
|
model/loginRequest.ts
|
||||||
model/metrics.ts
|
model/metrics.ts
|
||||||
model/metricsSample.ts
|
model/metricsSample.ts
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { RequestFile } from './models';
|
import { RequestFile } from './models';
|
||||||
import { GrantsRequest } from './grantsRequest';
|
import { ListOrganizationMembers200ResponseMembersInner } from './listOrganizationMembers200ResponseMembersInner';
|
||||||
|
|
||||||
export class ListOrganizationMembers200Response {
|
export class ListOrganizationMembers200Response {
|
||||||
'members'?: Array<GrantsRequest>;
|
'members'?: Array<ListOrganizationMembers200ResponseMembersInner>;
|
||||||
|
|
||||||
static discriminator: string | undefined = undefined;
|
static discriminator: string | undefined = undefined;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ export class ListOrganizationMembers200Response {
|
|||||||
{
|
{
|
||||||
"name": "members",
|
"name": "members",
|
||||||
"baseName": "members",
|
"baseName": "members",
|
||||||
"type": "Array<GrantsRequest>"
|
"type": "Array<ListOrganizationMembers200ResponseMembersInner>"
|
||||||
} ];
|
} ];
|
||||||
|
|
||||||
static getAttributeTypeMap() {
|
static getAttributeTypeMap() {
|
||||||
|
@ -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 ListOrganizationMembers200ResponseMembersInner {
|
||||||
|
'email'?: string;
|
||||||
|
'admin'?: boolean;
|
||||||
|
|
||||||
|
static discriminator: string | undefined = undefined;
|
||||||
|
|
||||||
|
static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"baseName": "email",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "admin",
|
||||||
|
"baseName": "admin",
|
||||||
|
"type": "boolean"
|
||||||
|
} ];
|
||||||
|
|
||||||
|
static getAttributeTypeMap() {
|
||||||
|
return ListOrganizationMembers200ResponseMembersInner.attributeTypeMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ export * from './grantsRequest';
|
|||||||
export * from './inviteRequest';
|
export * from './inviteRequest';
|
||||||
export * from './inviteTokenGenerateRequest';
|
export * from './inviteTokenGenerateRequest';
|
||||||
export * from './listOrganizationMembers200Response';
|
export * from './listOrganizationMembers200Response';
|
||||||
|
export * from './listOrganizationMembers200ResponseMembersInner';
|
||||||
export * from './loginRequest';
|
export * from './loginRequest';
|
||||||
export * from './metrics';
|
export * from './metrics';
|
||||||
export * from './metricsSample';
|
export * from './metricsSample';
|
||||||
@ -83,6 +84,7 @@ import { GrantsRequest } from './grantsRequest';
|
|||||||
import { InviteRequest } from './inviteRequest';
|
import { InviteRequest } from './inviteRequest';
|
||||||
import { InviteTokenGenerateRequest } from './inviteTokenGenerateRequest';
|
import { InviteTokenGenerateRequest } from './inviteTokenGenerateRequest';
|
||||||
import { ListOrganizationMembers200Response } from './listOrganizationMembers200Response';
|
import { ListOrganizationMembers200Response } from './listOrganizationMembers200Response';
|
||||||
|
import { ListOrganizationMembers200ResponseMembersInner } from './listOrganizationMembers200ResponseMembersInner';
|
||||||
import { LoginRequest } from './loginRequest';
|
import { LoginRequest } from './loginRequest';
|
||||||
import { Metrics } from './metrics';
|
import { Metrics } from './metrics';
|
||||||
import { MetricsSample } from './metricsSample';
|
import { MetricsSample } from './metricsSample';
|
||||||
@ -151,6 +153,7 @@ let typeMap: {[index: string]: any} = {
|
|||||||
"InviteRequest": InviteRequest,
|
"InviteRequest": InviteRequest,
|
||||||
"InviteTokenGenerateRequest": InviteTokenGenerateRequest,
|
"InviteTokenGenerateRequest": InviteTokenGenerateRequest,
|
||||||
"ListOrganizationMembers200Response": ListOrganizationMembers200Response,
|
"ListOrganizationMembers200Response": ListOrganizationMembers200Response,
|
||||||
|
"ListOrganizationMembers200ResponseMembersInner": ListOrganizationMembers200ResponseMembersInner,
|
||||||
"LoginRequest": LoginRequest,
|
"LoginRequest": LoginRequest,
|
||||||
"Metrics": Metrics,
|
"Metrics": Metrics,
|
||||||
"MetricsSample": MetricsSample,
|
"MetricsSample": MetricsSample,
|
||||||
|
@ -46,6 +46,7 @@ from zrok_api.models.grants_body import GrantsBody
|
|||||||
from zrok_api.models.identity_body import IdentityBody
|
from zrok_api.models.identity_body import IdentityBody
|
||||||
from zrok_api.models.inline_response200 import InlineResponse200
|
from zrok_api.models.inline_response200 import InlineResponse200
|
||||||
from zrok_api.models.inline_response2001 import InlineResponse2001
|
from zrok_api.models.inline_response2001 import InlineResponse2001
|
||||||
|
from zrok_api.models.inline_response2001_members import InlineResponse2001Members
|
||||||
from zrok_api.models.inline_response201 import InlineResponse201
|
from zrok_api.models.inline_response201 import InlineResponse201
|
||||||
from zrok_api.models.invite_request import InviteRequest
|
from zrok_api.models.invite_request import InviteRequest
|
||||||
from zrok_api.models.invite_token_generate_request import InviteTokenGenerateRequest
|
from zrok_api.models.invite_token_generate_request import InviteTokenGenerateRequest
|
||||||
|
@ -36,6 +36,7 @@ from zrok_api.models.grants_body import GrantsBody
|
|||||||
from zrok_api.models.identity_body import IdentityBody
|
from zrok_api.models.identity_body import IdentityBody
|
||||||
from zrok_api.models.inline_response200 import InlineResponse200
|
from zrok_api.models.inline_response200 import InlineResponse200
|
||||||
from zrok_api.models.inline_response2001 import InlineResponse2001
|
from zrok_api.models.inline_response2001 import InlineResponse2001
|
||||||
|
from zrok_api.models.inline_response2001_members import InlineResponse2001Members
|
||||||
from zrok_api.models.inline_response201 import InlineResponse201
|
from zrok_api.models.inline_response201 import InlineResponse201
|
||||||
from zrok_api.models.invite_request import InviteRequest
|
from zrok_api.models.invite_request import InviteRequest
|
||||||
from zrok_api.models.invite_token_generate_request import InviteTokenGenerateRequest
|
from zrok_api.models.invite_token_generate_request import InviteTokenGenerateRequest
|
||||||
|
@ -28,7 +28,7 @@ class InlineResponse2001(object):
|
|||||||
and the value is json key in definition.
|
and the value is json key in definition.
|
||||||
"""
|
"""
|
||||||
swagger_types = {
|
swagger_types = {
|
||||||
'members': 'list[GrantsBody]'
|
'members': 'list[InlineResponse2001Members]'
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_map = {
|
attribute_map = {
|
||||||
@ -48,7 +48,7 @@ class InlineResponse2001(object):
|
|||||||
|
|
||||||
|
|
||||||
:return: The members of this InlineResponse2001. # noqa: E501
|
:return: The members of this InlineResponse2001. # noqa: E501
|
||||||
:rtype: list[GrantsBody]
|
:rtype: list[InlineResponse2001Members]
|
||||||
"""
|
"""
|
||||||
return self._members
|
return self._members
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class InlineResponse2001(object):
|
|||||||
|
|
||||||
|
|
||||||
:param members: The members of this InlineResponse2001. # noqa: E501
|
:param members: The members of this InlineResponse2001. # noqa: E501
|
||||||
:type: list[GrantsBody]
|
:type: list[InlineResponse2001Members]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._members = members
|
self._members = members
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
zrok
|
||||||
|
|
||||||
|
zrok client access # noqa: E501
|
||||||
|
|
||||||
|
OpenAPI spec version: 0.3.0
|
||||||
|
|
||||||
|
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
class InlineResponse2001Members(object):
|
||||||
|
"""NOTE: This class is auto generated by the swagger code generator program.
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
Attributes:
|
||||||
|
swagger_types (dict): The key is attribute name
|
||||||
|
and the value is attribute type.
|
||||||
|
attribute_map (dict): The key is attribute name
|
||||||
|
and the value is json key in definition.
|
||||||
|
"""
|
||||||
|
swagger_types = {
|
||||||
|
'email': 'str',
|
||||||
|
'admin': 'bool'
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute_map = {
|
||||||
|
'email': 'email',
|
||||||
|
'admin': 'admin'
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, email=None, admin=None): # noqa: E501
|
||||||
|
"""InlineResponse2001Members - a model defined in Swagger""" # noqa: E501
|
||||||
|
self._email = None
|
||||||
|
self._admin = None
|
||||||
|
self.discriminator = None
|
||||||
|
if email is not None:
|
||||||
|
self.email = email
|
||||||
|
if admin is not None:
|
||||||
|
self.admin = admin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def email(self):
|
||||||
|
"""Gets the email of this InlineResponse2001Members. # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
:return: The email of this InlineResponse2001Members. # noqa: E501
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self._email
|
||||||
|
|
||||||
|
@email.setter
|
||||||
|
def email(self, email):
|
||||||
|
"""Sets the email of this InlineResponse2001Members.
|
||||||
|
|
||||||
|
|
||||||
|
:param email: The email of this InlineResponse2001Members. # noqa: E501
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._email = email
|
||||||
|
|
||||||
|
@property
|
||||||
|
def admin(self):
|
||||||
|
"""Gets the admin of this InlineResponse2001Members. # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
:return: The admin of this InlineResponse2001Members. # noqa: E501
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return self._admin
|
||||||
|
|
||||||
|
@admin.setter
|
||||||
|
def admin(self, admin):
|
||||||
|
"""Sets the admin of this InlineResponse2001Members.
|
||||||
|
|
||||||
|
|
||||||
|
:param admin: The admin of this InlineResponse2001Members. # noqa: E501
|
||||||
|
:type: bool
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._admin = admin
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
"""Returns the model properties as a dict"""
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
for attr, _ in six.iteritems(self.swagger_types):
|
||||||
|
value = getattr(self, attr)
|
||||||
|
if isinstance(value, list):
|
||||||
|
result[attr] = list(map(
|
||||||
|
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
||||||
|
value
|
||||||
|
))
|
||||||
|
elif hasattr(value, "to_dict"):
|
||||||
|
result[attr] = value.to_dict()
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
result[attr] = dict(map(
|
||||||
|
lambda item: (item[0], item[1].to_dict())
|
||||||
|
if hasattr(item[1], "to_dict") else item,
|
||||||
|
value.items()
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
result[attr] = value
|
||||||
|
if issubclass(InlineResponse2001Members, dict):
|
||||||
|
for key, value in self.items():
|
||||||
|
result[key] = value
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def to_str(self):
|
||||||
|
"""Returns the string representation of the model"""
|
||||||
|
return pprint.pformat(self.to_dict())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""For `print` and `pprint`"""
|
||||||
|
return self.to_str()
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
"""Returns true if both objects are equal"""
|
||||||
|
if not isinstance(other, InlineResponse2001Members):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self.__dict__ == other.__dict__
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
"""Returns true if both objects are not equal"""
|
||||||
|
return not self == other
|
@ -483,6 +483,8 @@ paths:
|
|||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
type: string
|
type: string
|
||||||
|
admin:
|
||||||
|
type: boolean
|
||||||
401:
|
401:
|
||||||
description: unauthorized
|
description: unauthorized
|
||||||
404:
|
404:
|
||||||
|
Loading…
Reference in New Issue
Block a user