diff --git a/internal/test/testing.go b/internal/test/testing.go index 2f194038..4e4fbaa4 100644 --- a/internal/test/testing.go +++ b/internal/test/testing.go @@ -100,13 +100,14 @@ type Test struct { AccessPackageResourceRoleClient *msgraph.AccessPackageResourceRoleClient AccessPackageResourceRoleScopeClient *msgraph.AccessPackageResourceRoleScopeClient AdministrativeUnitsClient *msgraph.AdministrativeUnitsClient + AppRoleAssignedToClient *msgraph.AppRoleAssignedToClient ApplicationTemplatesClient *msgraph.ApplicationTemplatesClient ApplicationsClient *msgraph.ApplicationsClient - AppRoleAssignedToClient *msgraph.AppRoleAssignedToClient AttributeSetClient *msgraph.AttributeSetClient AuthenticationMethodsClient *msgraph.AuthenticationMethodsClient AuthenticationStrengthPoliciesClient *msgraph.AuthenticationStrengthPoliciesClient B2CUserFlowClient *msgraph.B2CUserFlowClient + ChatClient *msgraph.ChatClient ClaimsMappingPolicyClient *msgraph.ClaimsMappingPolicyClient ConditionalAccessPoliciesClient *msgraph.ConditionalAccessPoliciesClient ConnectedOrganizationClient *msgraph.ConnectedOrganizationClient @@ -135,8 +136,8 @@ type Test struct { RoleAssignmentsClient *msgraph.RoleAssignmentsClient RoleDefinitionsClient *msgraph.RoleDefinitionsClient RoleEligibilityScheduleRequestClient *msgraph.RoleEligibilityScheduleRequestClient - RoleManagementPolicyClient *msgraph.RoleManagementPolicyClient RoleManagementPolicyAssignmentClient *msgraph.RoleManagementPolicyAssignmentClient + RoleManagementPolicyClient *msgraph.RoleManagementPolicyClient RoleManagementPolicyRuleClient *msgraph.RoleManagementPolicyRuleClient SchemaExtensionsClient *msgraph.SchemaExtensionsClient ServicePrincipalsAppRoleAssignmentsClient *msgraph.AppRoleAssignmentsClient @@ -282,6 +283,11 @@ func NewTest(t *testing.T) (c *Test) { c.B2CUserFlowClient.BaseClient.Endpoint = *endpoint c.B2CUserFlowClient.BaseClient.RetryableClient.RetryMax = retry + c.ChatClient = msgraph.NewChatClient() + c.ChatClient.BaseClient.Authorizer = c.Connections["default"].Authorizer + c.ChatClient.BaseClient.Endpoint = *endpoint + c.ChatClient.BaseClient.RetryableClient.RetryMax = retry + c.ClaimsMappingPolicyClient = msgraph.NewClaimsMappingPolicyClient() c.ClaimsMappingPolicyClient.BaseClient.Authorizer = c.Connections["default"].Authorizer c.ClaimsMappingPolicyClient.BaseClient.Endpoint = *endpoint diff --git a/msgraph/chat.go b/msgraph/chat.go new file mode 100644 index 00000000..b65889d4 --- /dev/null +++ b/msgraph/chat.go @@ -0,0 +1,176 @@ +package msgraph + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +const ( + ShortTypeChat string = "chat" + ShortTypeConversationMember string = "aadUserConversationMember" + TypeChat string = "#microsoft.graph.chat" + TypeConversationMember string = "#microsoft.graph.aadUserConversationMember" +) + +type ChatClient struct { + BaseClient Client +} + +func NewChatClient() *ChatClient { + return &ChatClient{ + BaseClient: NewClient(Version10), + } +} + +// Create creates a new chat. +func (c *ChatClient) Create(ctx context.Context, chat Chat) (*Chat, int, error) { + body, err := json.Marshal(chat) + if err != nil { + return nil, 0, fmt.Errorf("json.Marshal(): %v", err) + } + + retryFunc := func(resp *http.Response, o *odata.OData) bool { + if resp != nil && o != nil && o.Error != nil { + if resp.StatusCode == http.StatusForbidden { + return o.Error.Match("One or more members cannot be added to the thread roster") + } + } + return false + } + + resp, status, _, err := c.BaseClient.Post(ctx, PostHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: retryFunc, + OData: odata.Query{ + Metadata: odata.MetadataFull, + }, + ValidStatusCodes: []int{http.StatusCreated}, + Uri: Uri{ + Entity: "/chats", + }, + }) + + if err != nil { + return nil, status, fmt.Errorf("ChatsClient.BaseClient.Post(): %v", err) + } + + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + + var newChat Chat + if err := json.Unmarshal(respBody, &newChat); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + + return &newChat, status, nil +} + +// Get retrieves a chat. +func (c *ChatClient) Get(ctx context.Context, id string, query odata.Query) (*Chat, int, error) { + query.Metadata = odata.MetadataFull + + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + OData: query, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/chats/%s", id), + }, + }) + if err != nil { + return nil, status, fmt.Errorf("ChatsClient.BaseClient.Get(): %v", err) + } + + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + + var chat Chat + if err := json.Unmarshal(respBody, &chat); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + + return &chat, status, nil +} + +// List returns a list of chats as Chat objects. +// To return just a lost of IDs then place the query to be Odata.Query{Select: "id"}. +func (c *ChatClient) List(ctx context.Context, userID string, query odata.Query) (*[]Chat, int, error) { + query.Metadata = odata.MetadataFull + + resp, status, _, err := c.BaseClient.Get(ctx, GetHttpRequestInput{ + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + OData: query, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/users/%s/chats", userID), + }, + }) + if err != nil { + return nil, status, fmt.Errorf("ChatsClient.BaseClient.Get(): %v", err) + } + + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, status, fmt.Errorf("io.ReadAll(): %v", err) + } + + var chatList struct { + Value []Chat `json:"value"` + } + if err := json.Unmarshal(respBody, &chatList); err != nil { + return nil, status, fmt.Errorf("json.Unmarshal(): %v", err) + } + + return &chatList.Value, status, nil + +} + +// Update updates a chat. +func (c *ChatClient) Update(ctx context.Context, chat Chat) (int, error) { + body, err := json.Marshal(chat) + if err != nil { + return 0, fmt.Errorf("json.Marshal(): %v", err) + } + + _, status, _, err := c.BaseClient.Patch(ctx, PatchHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusNoContent}, + Uri: Uri{ + Entity: fmt.Sprintf("/chats/%s", *chat.ID), + }, + }) + if err != nil { + return status, fmt.Errorf("ChatsClient.BaseClient.Patch(): %v", err) + } + + return status, nil +} + +// Delete deletes a chat. +func (c *ChatClient) Delete(ctx context.Context, chatId string) (int, error) { + _, status, _, err := c.BaseClient.Delete(ctx, DeleteHttpRequestInput{ + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusNoContent}, + Uri: Uri{ + Entity: fmt.Sprintf("/chats/%s", chatId), + }, + }) + if err != nil { + return status, fmt.Errorf("ChatsClient.BaseClient.Delete(): %v", err) + } + + return status, nil +} diff --git a/msgraph/chat_test.go b/msgraph/chat_test.go new file mode 100644 index 00000000..e918e288 --- /dev/null +++ b/msgraph/chat_test.go @@ -0,0 +1,136 @@ +package msgraph_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/manicminer/hamilton/internal/test" + "github.com/manicminer/hamilton/internal/utils" + "github.com/manicminer/hamilton/msgraph" +) + +func TestChatClient(t *testing.T) { + c := test.NewTest(t) + defer c.CancelFunc() + + self := testDirectoryObjectsClient_Get(t, c, c.Claims.ObjectId) + + // To create a chat two users need to be assigned to the chat. + // An owner needs to be assigned + user1 := testUsersClient_Create(t, c, msgraph.User{ + AccountEnabled: utils.BoolPtr(true), + DisplayName: utils.StringPtr("test-user1"), + MailNickname: utils.StringPtr(fmt.Sprintf("test-user1-%s", c.RandomString)), + UserPrincipalName: utils.StringPtr(fmt.Sprintf("test-user1-%s@%s", c.RandomString, c.Connections["default"].DomainName)), + PasswordProfile: &msgraph.UserPasswordProfile{ + Password: utils.StringPtr(fmt.Sprintf("IrPa55w0rd%s", c.RandomString)), + }, + }) + defer testUsersClient_Delete(t, c, *user1.ID()) + + user2 := testUsersClient_Create(t, c, msgraph.User{ + AccountEnabled: utils.BoolPtr(true), + DisplayName: utils.StringPtr("test-user2"), + MailNickname: utils.StringPtr(fmt.Sprintf("test-user2-%s", c.RandomString)), + UserPrincipalName: utils.StringPtr(fmt.Sprintf("test-user2-%s@%s", c.RandomString, c.Connections["default"].DomainName)), + PasswordProfile: &msgraph.UserPasswordProfile{ + Password: utils.StringPtr(fmt.Sprintf("IrPa55w0rd%s", c.RandomString)), + }, + }) + defer testUsersClient_Delete(t, c, *user2.ID()) + + // Check that a group chat and a OneOnOne chat can be created + newChat := msgraph.Chat{ + Topic: utils.StringPtr(fmt.Sprintf("test-chat-%s", c.RandomString)), + ChatType: utils.StringPtr(msgraph.ChatTypeGroup), + Members: &[]msgraph.ConversationMember{ + { + ODataType: utils.StringPtr(msgraph.TypeConversationMember), + User: utils.StringPtr(fmt.Sprintf("https://graph.microsoft.com/v1.0/users('%s')", *user1.Id)), + Roles: &[]string{"owner"}, + }, + { + ODataType: utils.StringPtr(msgraph.TypeConversationMember), + User: utils.StringPtr(fmt.Sprintf("https://graph.microsoft.com/v1.0/users('%s')", *user2.Id)), + Roles: &[]string{"owner"}, + }, + { + ODataType: utils.StringPtr(msgraph.TypeConversationMember), + User: utils.StringPtr(fmt.Sprintf("https://graph.microsoft.com/v1.0/users('%s')", *self.Id)), + Roles: &[]string{"owner"}, + }, + }, + } + + chat := testChatClient_Create(t, c, newChat) + defer testChatClient_Delete(t, c, *chat.ID) + testChatClient_Get(t, c, *chat.ID) + testChatClient_List(t, c, *self.Id) + + chat.Topic = utils.StringPtr(fmt.Sprintf("test-chat-archived-%s", c.RandomString)) + chat.Viewpoint.IsHidden = utils.BoolPtr(true) + testChatClient_Update(t, c, *chat) +} + +func testChatClient_Create(t *testing.T, c *test.Test, newChat msgraph.Chat) (chat *msgraph.Chat) { + chat, status, err := c.ChatClient.Create(c.Context, newChat) + if err != nil { + t.Fatalf("ChatClient.Create(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("ChatClient.Create(): invalid status: %d", status) + } + if chat == nil { + t.Fatal("ChatClient.Create(): chat was nil") + } + return +} + +func testChatClient_Get(t *testing.T, c *test.Test, id string) (chat *msgraph.Chat) { + chat, status, err := c.ChatClient.Get(c.Context, id, odata.Query{}) + if err != nil { + t.Fatalf("ChatClient.Get(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("ChatClient.Get(): invalid status: %d", status) + } + if chat == nil { + t.Fatal("ChatClient.Get(): chat was nil") + } + return +} + +func testChatClient_List(t *testing.T, c *test.Test, userID string) (chats *[]msgraph.Chat) { + chats, _, err := c.ChatClient.List(c.Context, userID, odata.Query{Top: 10}) + if err != nil { + t.Fatalf("ChatClient.List(): %v", err) + } + if chats == nil { + t.Fatal("ChatClient.List(): chats was nil") + } + return +} + +func testChatClient_Update(t *testing.T, c *test.Test, chat msgraph.Chat) (updatedChat *msgraph.Chat) { + chat.Topic = utils.StringPtr(fmt.Sprintf("test-chat-%s", c.RandomString)) + status, err := c.ChatClient.Update(c.Context, chat) + if err != nil { + t.Fatalf("ChatClient.Update(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("ChatClient.Update(): invalid status: %d", status) + } + return +} + +func testChatClient_Delete(t *testing.T, c *test.Test, chatId string) { + status, err := c.ChatClient.Delete(c.Context, chatId) + if err != nil { + t.Fatalf("ChatClient.Delete(): %v", err) + } + if status < 200 || status >= 300 { + t.Fatalf("ChatClient.Delete(): invalid status: %d", status) + } + return +} diff --git a/msgraph/models.go b/msgraph/models.go index d542facb..7a6d626d 100644 --- a/msgraph/models.go +++ b/msgraph/models.go @@ -617,6 +617,138 @@ type BaseNamedLocation struct { ModifiedDateTime *time.Time `json:"modifiedDateTime,omitempty"` } +type ChannelIdentity struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ChannelId *string `json:"channelId,omitempty"` + TeamId *string `json:"teamId,omitempty"` +} + +type Chat struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + CreatedDateTIme *time.Time `json:"createdDateTime,omitempty"` + ChatType *ChatType `json:"chatType,omitempty"` + LastUpdatedDateTime *time.Time `json:"lastUpdatedDateTime,omitempty"` + OnlineMeetingInfo *TeamworkOnlineMeetingInfo `json:"onlineMeetingInfo,omitempty"` + TenantId *string `json:"tenantId,omitempty"` + Topic *string `json:"topic,omitempty"` + Viewpoint *ChatViewpoint `json:"viewpoint,omitempty"` + WebURL *string `json:"webUrl,omitempty"` + InstalledApps *TeamsAppInstallation `json:"installedApps,omitempty"` + LastMessagePreview *ChatMessageInfo `json:"lastMessagePreview,omitempty"` + Members *[]ConversationMember `json:"members,omitempty"` + Messages *[]ChatMessage `json:"messages,omitempty"` + PinnedMessages *[]PinnedChatMessageInfo `json:"pinnedMessages,omitempty"` + Tabs *TeamsTab `json:"tabs,omitempty"` +} + +type ChatMessage struct { + Attachments *[]ChatMessageAttachment `json:"attachments"` + Body *ItemBody `json:"body"` + ChannelIdentity *ChannelIdentity `json:"channelIdentity"` + ChatId *string `json:"chatId"` + CreatedDateTime *time.Time `json:"createdDateTime"` + DeletedDateTime *time.Time `json:"deletedDateTime"` + Etag *string `json:"etag"` + EventDetail *EventMessageDetail `json:"eventDetail"` + From *ChatMessageFromIdentitySet `json:"from"` + ID *string `json:"id"` + Importance *string `json:"importance"` + LastEditedDateTime *time.Time `json:"lastEditedDateTime"` + LastModifiedDateTime *time.Time `json:"lastModifiedDateTime"` + Locale *string `json:"locale"` + Mentions *[]ChatMessageMention `json:"mentions"` + MessageType *MessageType `json:"messageType"` + PolicyViolation *ChatMessagePolicyViolation `json:"policyViolation"` + Reactions *[]ChatMessageReaction `json:"reactions"` + ReplyToId *string `json:"replyToId"` + Subject *string `json:"subject"` + Summary *string `json:"summary"` + WebUrl *string `json:"webUrl"` +} + +type ChatMessageAttachment struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + Content *string `json:"content"` + ContentType *string `json:"contentType"` + ContentUrl *string `json:"contentUrl"` + Id *string `json:"id"` + Name *string `json:"name"` + TeamsAppId *string `json:"teamsAppId"` + ThumbnailUrl *string `json:"thumbnailUrl"` +} + +type ChatMessageFromIdentitySet struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + Application *Application `json:"application,omitempty"` + Device *struct { + OdataType string `json:"@odata.type"` + } `json:"device,omitempty"` + User *User `json:"user,omitempty"` +} + +type ChatMessageInfo struct { + Body *ItemBody `json:"body"` + CreatedDateTime *time.Time `json:"createdDateTime"` + EventDetail *EventMessageDetail `json:"eventDetail"` + From *ChatMessageFromIdentitySet `json:"from"` + ID *string `json:"id"` + IsDeleted *bool `json:"isDeleted"` + MessageType *ChatMessageType `json:"messageType"` +} + +type ChatMessageMention struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *int32 `json:"id,omitempty"` + Mentioned *ChatMessageMentionedIdentitySet `json:"mentioned,omitempty"` + MentionText *string `json:"mentionText,omitempty"` +} + +type ChatMessageMentionedIdentitySet struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + Application *Application `json:"application,omitempty"` + Conversation *TeamworkConversationIdentity `json:"conversation,omitempty"` + Device *struct { + OdataType string `json:"@odata.type"` + } `json:"device,omitempty"` + User *User `json:"user,omitempty"` +} + +type ChatMessagePolicyTip struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ComplianceURL *string `json:"complianceUrl,omitempty"` + GeneralText *string `json:"generalText,omitempty"` + MatchedConditionDescriptions *[]string `json:"matchedConditionDescriptions,omitempty"` +} + +type ChatMessagePolicyViolation struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + DLPAction *string `json:"dlpAction,omitempty"` + JustificationText *string `json:"justificationText,omitempty"` + PolicyTip *ChatMessagePolicyTip `json:"policyTip,omitempty"` + UserAction *UserAction `json:"userAction,omitempty"` + VerdictDetails *VerdictDetails `json:"verdictDetails,omitempty"` +} + +type ChatMessageReaction struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + CreatedDateTime *time.Time `json:"createdDateTime,omitempty"` // This is always UTC format according to docs + ReactionType *ReactionType `json:"reactionType,omitempty"` + User *ChatMessageReactionIdentitySet `json:"user,omitempty"` +} + +type ChatMessageReactionIdentitySet struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + // Application and Device are also returned but omitted as they are never set + User *Identity `json:"user,omitempty"` +} + +type ChatViewpoint struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + IsHidden *bool `json:"isHidden,omitempty"` + LastMessageReadDateTime *time.Time `json:"lastMessageReadDateTime,omitempty"` +} + type ClaimsMappingPolicy struct { DirectoryObject Definition *[]string `json:"definition,omitempty"` @@ -788,6 +920,15 @@ type ConnectionInfo struct { Url *string `json:"url,omitempty"` } +type ConversationMember struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + User *string `json:"user@odata.bind,omitempty"` + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Roles *[]string `json:"roles,omitempty"` + VisibleHistoryStartDateTime *time.Time `json:"visibleHistoryStartDateTime,omitempty"` +} + // CountryNamedLocation describes an Country Named Location object. type CountryNamedLocation struct { *BaseNamedLocation @@ -1024,6 +1165,12 @@ type EntitlementManagementSchedule struct { Recurrence *RecurrencePattern `json:"recurrence,omitempty"` } +// EventMessageDetail is just an OData representation that is not applied +// https://learn.microsoft.com/en-us/graph/api/resources/eventmessagedetail?view=graph-rest-1.0 +type EventMessageDetail struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` +} + type ExtensionSchemaProperty struct { Name *string `json:"name,omitempty"` Type ExtensionSchemaPropertyDataType `json:"type,omitempty"` @@ -1437,6 +1584,12 @@ type PhoneAuthenticationMethod struct { PhoneType *AuthenticationPhoneType `json:"phoneType,omitempty"` } +type PinnedChatMessageInfo struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + Message *ChatMessage `json:"message,omitempty"` +} + type PrivilegedAccessGroupAssignmentSchedule struct { ID *string `json:"id,omitempty"` AccessId PrivilegedAccessGroupRelationship `json:"accessId,omitempty"` @@ -1811,6 +1964,69 @@ type TargetResource struct { ModifiedProperties *[]ModifiedProperty `json:"modifiedProperties,omitempty"` } +type TeamsApp struct { + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + DistributionMethod *TeamsAppDistributionMethod `json:"distributionMethod,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + AppDefinitions *[]TeamsAppDefinition `json:"appDefinitions,omitempty"` +} + +type TeamsAppDefinition struct { + ID *string `json:"id,omitempty"` + TeamsAppId *string `json:"teamsAppId,omitempty"` + Version *string `json:"version,omitempty"` + Description *string `json:"description,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + PublishingState *TeamsAppPublishingState `json:"publishingState,omitempty"` + Bot *TeamWorkBot `json:"bot,omitempty"` +} + +type TeamsAppInstallation struct { + ID *string `json:"id,omitempty"` + TeamsApp *TeamsApp `json:"teamsApp,omitempty"` +} + +type TeamsTab struct { + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + WebUrl *string `json:"webUrl,omitempty"` + TeamsApp *TeamsApp `json:"teamsApp,omitempty"` + Configuration *TeamsTabConfiguration `json:"configuration,omitempty"` +} + +type TeamsTabConfiguration struct { + EntityId *string `json:"entityId,omitempty"` + ContentUrl *string `json:"contentUrl,omitempty"` + RemoveUrl *string `json:"removeUrl,omitempty"` + WebsiteUrl *string `json:"websiteUrl,omitempty"` +} + +type TeamWorkBot struct { + ID *string `json:"id,omitempty"` + ODataType *odata.Type `json:"@odata.type,omitempty"` +} + +type TeamworkConversationIdentity struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + ConversationIdentityType *ConversationIdentityType `json:"conversationIdentityType,omitempty"` +} + +type TeamworkOnlineMeetingInfo struct { + CalendarEventID *string `json:"calendarEventId,omitempty"` + JoinWebURL *string `json:"joinWebUrl,omitempty"` + Organizer *TeamworkUserIdentity `json:"organizer,omitempty"` +} + +type TeamworkUserIdentity struct { + ODataType *odata.Type `json:"@odata.type,omitempty"` + ID *string `json:"id,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + UserIdentityType *TeamworkUserIdentityType `json:"userIdentityType,omitempty"` +} + type TermsOfUseAgreement struct { ID *string `json:"id,omitempty"` DisplayName *string `json:"displayName,omitempty"` diff --git a/msgraph/valuetypes.go b/msgraph/valuetypes.go index 0d7efb83..81cf1343 100644 --- a/msgraph/valuetypes.go +++ b/msgraph/valuetypes.go @@ -311,6 +311,23 @@ const ( BodyTypeHtml BodyType = "html" ) +type ChatMessageType = string + +const ( + ChatMessageTypeMessage ChatMessageType = "message" + ChatMessageTypeUnknownFutureValue ChatMessageType = "unknownFutureValue" + ChatMessageTypeSystemEventMessage ChatMessageType = "systemEventMessage" +) + +type ChatType = string + +const ( + ChatTypeGroup ChatType = "group" + ChatTypeOneOnOne ChatType = "oneOnOne" + ChatTypeMeeting ChatType = "meeting" + ChatTypeUnknownFutureValue ChatType = "unknownFutureValue" +) + type ConsentProvidedForMinor = StringNullWhenEmpty const ( @@ -465,6 +482,15 @@ const ( ConnectedOrganizationStateUnknownFutureValue ConnectedOrganizationState = "unknownFutureValue" ) +type ConversationIdentityType = string + +const ( + ConversationIdentityTypeTeam ConversationIdentityType = "team" + ConversationIdentityTypeChat ConversationIdentityType = "chat" + ConversationIdentityTypeChannel ConversationIdentityType = "channel" + ConversationIdentityTypeUnknownFutureValue ConversationIdentityType = "unknownFutureValue" +) + type DaysOfWeekType = string const ( @@ -699,6 +725,16 @@ func (o *Members) UnmarshalJSON(data []byte) error { return nil } +type MessageType = string + +const ( + MessageTypeMessage MessageType = "Message" + MessageTypeChatEvent MessageType = "ChatEvent" + MessageTypeTyping MessageType = "Typing" + MessageTypeUnknownFutureValue MessageType = "UnknownFutureValue" + MessageTypeSystemEventMessage MessageType = "SystemEventMessage" +) + type MethodUsabilityReason string const ( @@ -825,6 +861,17 @@ const ( PrivilegedAccessGroupRelationshipUnknown PrivilegedAccessGroupRelationship = "unknownFutureValue" ) +type ReactionType = string + +const ( + ReactionTypeLike ReactionType = "like" + ReactionTypeAngry ReactionType = "angry" + ReactionTypeSad ReactionType = "sad" + ReactionTypeLaugh ReactionType = "laugh" + ReactionTypeHeart ReactionType = "heart" + ReactionTypeSurprised ReactionType = "surprised" +) + type RecurrencePatternType = string const ( @@ -909,6 +956,36 @@ const ( SignInAudiencePersonalMicrosoftAccount SignInAudience = "PersonalMicrosoftAccount" ) +type TeamsAppDistributionMethod = string + +const ( + TeamsAppDistributionMethodStore TeamsAppDistributionMethod = "store" + TeamsAppDistributionMethodOrganization TeamsAppDistributionMethod = "organization" + TeamsAppDistributionMethodSideloaded TeamsAppDistributionMethod = "sideloaded" +) + +type TeamsAppPublishingState = string + +const ( + TeamsAppPublishingStateSubmitted TeamsAppPublishingState = "submitted" + TeamsAppPublishingStatePublished TeamsAppPublishingState = "published" + TeamsAppPublishingStateRejected TeamsAppPublishingState = "rejected" +) + +type TeamworkUserIdentityType string + +const ( + TeamworkUserIdentityTypeAadUser TeamworkUserIdentityType = "aadUser" + TeamworkUserIdentityOnPremiseAadUser TeamworkUserIdentityType = "onPremiseAadUser" + TeamworkUserIdentityAnonymousGuest TeamworkUserIdentityType = "anonymousGuest" + TeamworkUserIdentityFederatedUser TeamworkUserIdentityType = "federatedUser" + TeamworkUserIdentityPersonalMicrosoftAccountUser TeamworkUserIdentityType = "personalMicrosoftAccountUser" + TeamworkUserIdentitySkypeUser TeamworkUserIdentityType = "skypeUser" + TeamworkUserIdentityPhoneUser TeamworkUserIdentityType = "phoneUser" + TeamworkUserIdentityUnknownFutureValue TeamworkUserIdentityType = "unknownFutureValue" + TeamworkUserIdentityEmailUser TeamworkUserIdentityType = "emailUser" +) + type UnifiedRoleScheduleRequestAction = string const ( @@ -1015,6 +1092,14 @@ const ( IncludedUserTypesGuest IncludedUserTypes = "guest" ) +type UserAction = string + +const ( + UserActionNone UserAction = "none" + UserActionOverride UserAction = "override" + UserActionReportFalsePositive UserAction = "reportFalsePositive" +) + type UserflowAttributeDataType = string const ( @@ -1035,6 +1120,15 @@ const ( IndexTypeLast IndexType = "last" ) +type VerdictDetails = string + +const ( + VerdictDetailsNone VerdictDetails = "none" + VerdictDetailsAllowFalsePositiveOverride VerdictDetails = "allowFalsePositiveOverride" + VerdictDetailsAllowOverrideWithoutJustification VerdictDetails = "allowOverrideWithoutJustification" + VerdictDetailsAllowOverrideWithJustification VerdictDetails = "allowOverrideWithJustification" +) + type WindowsAutopilotDeviceType = string const (